Capybara 和 Factorybot - 创建的数据没有出现

Capybara and Factorybot - created data does not appear

我遇到了有线问题,factoryBot 正在 Db 中创建记录,但是当水豚尝试访问它时,HTML 中没有记录。

我尝试使用 "byebug" 进行调试,当我说 @topics => 它给了我零数据。 (@topic 是 topics_controller.rb -> 索引方法中的实例变量)

如果我这样做 "Topic.all.first" 它会向我显示正确的主题记录以及预期的随机名称 -> "Toys & Garden" 如果我这样做 "random_topic.name" -> "Toys & Garden"

我在其他功能中有一些类似的设置,即 "account creation feature",它在那里工作正常。任何指示或帮助将不胜感激。

我的出厂文件是

FactoryBot.define do
  factory :topic do
    name { Faker::Commerce.department(2, true) }
    archived false
  end
end

我的功能规范文件如下所示

require 'rails_helper'

describe "topics" do
  let(:user) {create(:user)} 

  before do 
    sign_user_in(user)  #support fuction to sign user in

  end 

  it "allows topics to be edited" do
    random_topic = create(:topic)
    visit topics_path   # /topics/ 
    expect(page).to have_text random_topic.name   # Error1 

    click_edit_topic_button random_topic.name  # Another support fuction 
    random_topic_name_2 = Faker::Commerce.department(2, true)
    fill_in "Name", with: random_topic_name_2
    check "Archived"
    click_button "Update Topic"

    expect(page).to have_text "Topic updated!"
    expect(page).to have_text random_topic_name_2
  end
end

我在标记为 "Error 1" 的行上收到错误,请注意 "Toys & Garden" 是 Faker Gem 生成的样本名称。

Failure/Error: expect(page).to have_text random_topic.name
       expected #has_text?("Toys & Garden") to return true, got false

我的 Rails helper(rails_helper.rb) 文件设置如下。

# This file is copied to spec/ when you run 'rails generate rspec:install'

require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'database_cleaner'
require 'capybara/rspec'
require 'shoulda/matchers'
require 'email_spec'
require "email_spec/rspec"


Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

ActiveRecord::Migration.maintain_test_schema!

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

# This is for setting up Capybara right host.
#  
def set_host (host)
  default_url_options[:host] = host
  Capybara.app_host = "http://" + host
end

RSpec.configure do |config|

  config.include Capybara::DSL

  config.include Rails.application.routes.url_helpers

  config.include FactoryBot::Syntax::Methods
  config.include EmailSpec::Helpers
  config.include EmailSpec::Matchers

  config.order = "random"

  config.use_transactional_fixtures = false

  config.before(:each) do
    set_host "lvh.me:3000"
  end

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

end

我的主题控制器文件如下所示

class TopicsController < ApplicationController

  layout 'dashboard'
  before_action :authenticate_user!


  def index
    @topics = Topic.all
  end

end

已更新 @smallbutton.com 评论,但问题仍在继续。

已解决

我正在使用公寓 gem,因此在测试调查各个租户时,主题是在 public 架构中创建的。

根据@thomas的建议,我修改了代码:

  before do 
    set_subdomain(account.subdomain)
    sign_user_in(user)  #support fuction to sign user in
    Apartment::Tenant.switch!(account.subdomain)
  end 

您应该在访问页面之前创建记录。目前您以相反的方式进行操作,因此您的记录不会出现。

当您访问该页面时,您的记录不会保留,因此 return false.

是正常的

尝试以下操作:

require 'rails_helper'

describe "topics" do
  let(:user) {create(:user)}
  let!(:random_topic) {create(:topic)}

  before do 
    sign_user_in(user)  #support fuction to sign user in
    visit topics_path   # /topics/ 
  end 

  it "allows topics to be edited" do
    expect(page).to have_text random_topic.name   # Error1 

    click_edit_topic_button random_topic.name  # Another support fuction 
    random_topic_name_2 = Faker::Commerce.department(2, true)
    fill_in "Name", with: random_topic_name_2
    check "Archived"
    click_button "Update Topic"

    expect(page).to have_text "Topic updated!"
    expect(page).to have_text random_topic_name_2
  end
end

请注意 random_topic 是在 let! 中提取的(有关 之间差异的更多信息让让!https://relishapp.com/rspec/rspec-core/v/2-5/docs/helper-methods/let-and-let

发生这种情况通常是由以下几种情况之一引起的

  1. 实际上并没有创建记录

    从你的代码来看,它似乎不是

  2. 记录是在一个事务中创建的,而应用程序在另一个事务中运行正在创建。

    您似乎 database_cleaner 配置正确,这在您的情况下应该不是问题,但是您应该使用 - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example - 而不是您拥有的配置(这取决于在 :js 元数据上,而不是检查实际使用的是哪个驱动程序)

  3. 用户已将 Capybara 配置为访问与测试实际 运行 所在服务器不同的服务器。

    这里我们似乎遇到了问题,因为您将 Capybara.app_host 配置为 'lvh.me:3000'。端口 3000 是您的开发应用程序通常 运行 使用的端口,而 Capybara(默认情况下)在随机端口上启动您的应用程序以进行测试。这可能意味着你的测试实际上是 运行ning 针对你的开发 app/db 实例,这与测试 app/db 实例无关,因此测试不会看到你在你的测试。删除 Capybara.app_host 的设置,除非你确实需要它的设置(在这种情况下,从你的 app_host 设置中删除端口并启用 Capybara.always_include_server_port

话虽这么说,因为您使用的是 Rails 5.1+ database_cleaner 应该不再需要了。您应该能够删除所有 database_cleaner,重新启用 use_transactional_fixtures,并设置 Capybara.server = :puma 并且一切正常(仍然需要修复 app_host 设置)

遇到此类问题的人一定要试试这个:

instance.reload 点击之后和使用“expect”之前。

这解决了我困扰了一整天的问题...