【问题标题】:Rails: Can not save on DB during rspec features testRails:在 rspec 功能测试期间无法保存在数据库上
【发布时间】:2015-01-25 10:59:45
【问题描述】:

我正在使用 rspec 执行功能测试,在登录之前我无法将用户保存在数据库中。 我正在使用工厂女孩来构建对象。 夹具在测试开始时保存在db中,但最后没有被删除。(可能是因为测试失败。我不知道)

所以在点击登录之前我无法保存用户并收到此错误消息

-- 弃用警告:为 Devise::Strategies::DatabaseAuthenticatable#validate 提供了一个空资源。请确保资源不为零。 (从 app/controllers/application_controller.rb:43 处的 set_required_vars 调用)

spec/features/login_to_mainpage_spec.rb(没有错误被挽救)

require "rails_helper"

feature 'Navigating to homepage' do
  let(:user) { create(:user) }
  let(:login_page) { MainLoginPage.new }

  scenario "login" do
    login_page.visit_page.login(user)
    sleep(20)
  end
end

一个简单的页面对象:spec/features/pages_objects/main_login_page.rb

class MainLoginPage
  include Capybara::DSL

  def login(user)
    fill_in 'email', with: user.email
    fill_in 'password', with: "password"
    click_on 'logIn'
  end

  def visit_page
    visit '/'
    self
  end
end

我的 rails_helper

require 'spec_helper'
require 'capybara/rspec'
require 'capybara/poltergeist'
require "selenium-webdriver"
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
Dir[Rails.root.join("spec/features/page_objects/**/*.rb")].each { |f| require f }

RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = false
  config.before :each do
    DatabaseCleaner.start
  end
  config.after :each do
    DatabaseCleaner.clean
  end

  config.infer_spec_type_from_file_location!

  config.include Devise::TestHelpers, :type => :controller
end

Capybara.default_driver = :selenium
Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, :browser => :firefox)
end

在规范助手中:

require 'simplecov'
require 'factory_girl'
require 'rspec/autorun'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'


ENV["RAILS_ENV"] ||= 'test'
RSpec.configure do |config|
  include ActionDispatch::TestProcess
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end

  config.mock_with :rspec do |mocks|
    mocks.verify_partial_doubles = true
  end
  config.disable_monkey_patching!

  if config.files_to_run.one?
    config.default_formatter = 'doc'
  end

  config.profile_examples = 10

  config.order = :random

  Kernel.srand config.seed
end

编辑 1

我将“gem 'factory_girl'”切换为“gem 'factory_girl_rails'”

并将其添加到 application.rb

config.generators do
|g|
  g.test_framework :rspec,
                   :fixtures => true,
                   :view_specs => false,
                   :helper_specs => false,
                   :routing_specs => false,
                   :controller_specs => true,
                   :request_specs => true
  g.fixture_replacement :factory_girl, :dir => "spec/factories"
end

我仍然无法将用户保存在数据库中。 一切都过去了,但我通过代码输入了一些 sleep(10) 以刷新我的数据库并查看 te 记录,并且永远不会保存用户

编辑 3

我的问题其实很简单。如果我放入 rails_helper,FactoryGirl.create 永远不会将数据保存在数据库中:

config.use_transactional_fixtures = true

config.before :each do
 DatabaseCleaner.start
end
config.after :each do
 DatabaseCleaner.clean
end

/规格/工厂

FactoryGirl.define do
  factory :user  do
    email 'pierre@tralala.com'
    password 'password'
    password_confirmation 'password'
end

/spec/support/factory_girl.rb

RSpec.configure do |config|
  config.include FactoryGirl::Syntax::Methods
end

spec/features/login_to_mainpage_spec.rb

let(:user) { create(:user) }
scenario "login" do
  login_page.visit_page.login(create(:user))
  sleep(5)
end

由于我之前引用的配置,用户将不会被保存。 我需要在测试之间重置数据。

编辑 4

如果我使用控制台

RAILS_ENV=test rails c
FactoryGirl.create(:user) it is saved in db.

我不明白为什么它在我的测试中不起作用。

【问题讨论】:

    标签: ruby-on-rails rspec capybara


    【解决方案1】:

    尝试使用let! 创建您的用户。 来自rSpec documentation

    注意 let 是惰性求值的:直到第一次才求值 它定义的方法被调用。你可以使用让!强制方法的 在每个示例之前调用。

    【讨论】:

      【解决方案2】:

      使用 FactoryGirl 为您提供序列的独特字段解决您​​的问题:

      sequence :email do |n|
          "person#{n}@example.com"
      end
      
      factory :user do
          email { generate(:email }
      end
      

      这将以“person1@example.com”开头,每次调用 FactoryGirl.create(:user) 时都会在数字上加 1。

      【讨论】:

        【解决方案3】:

        您说您正在使用 FactoryGirl,但我在您的测试中没有看到这一点。要使用 FactoryGirl 创建我的用户,我总是这样做:

        FactoryGirl.create(:user, password: 'test', password_confirmation: 'test', name: 'test')
        

        如果你的工厂设置正确,你可以写:

        FactoryGirl.create(:user)
        

        【讨论】:

        • 谢谢,我要试试这个
        • 我做了很多调整,但我仍然有问题。我将“factory_girl”gem 切换为“factory_girl_rails”gem,但工厂仍然没有将用户保存在数据库中
        • 您确定用户没有保存到数据库中,还是您的登录失败是由于其他原因。您也可以尝试删除 rails_helper 中的 DataBaseCleaner 以查看此 gem 是否存在问题。
        • 是的,你是对的。现在它可以工作了,但是我所有的单元测试都失败了,因为它们使用了 DatabaseCleaner。 -> ActiveRecord::RecordInvalid: 验证失败:电子邮件已被使用。我怎样才能让一切正常?单元测试+功能测试
        猜你喜欢
        • 1970-01-01
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-28
        • 1970-01-01
        • 2015-07-25
        • 1970-01-01
        相关资源
        最近更新 更多