每当我运行用户测试时,RSpec会在测试完成后将Fabricated用户留在测试数据库中,这会弄乱我的其他测试。我将执行rake db:test:prepare
,但是当我再次运行测试时,会在我的数据库中重新创建记录。我不知道为什么会这样。它只发生在用户对象上。
在我的spec_helper文件中,我甚至有:
config.use_transactional_fixtures = true
以下是创建记录的示例测试:
it "creates a password reset token for the user" do
alice = Fabricate(:user)
post :create, email: alice.email
expect(assigns(alice.password_reset_token)).to_not eq(nil)
end
制造商:
Fabricator(:user) do
email { Faker::Internet.email }
password 'password'
name { Faker::Name.name }
end
这可能与我的用户模型有关吗?
答案 0 :(得分:20)
你应该使用一个名为database_cleaner的gem来截断你的数据库并自动重置所有内容,所以在你的gem文件中添加gem database_cleaner之后你的spec_helper.rb配置它
spec_helper.rb
config.use_transactional_fixtures = false
config.before(:suite) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
然后在spec / support目录中创建一个新文件
规格/支持/ shared_db_connection.rb
class ActiveRecord::Base
mattr_accessor :shared_connection
@@shared_connection = nil
def self.connection
@@shared_connection || retrieve_connection
end
end
ActiveRecord::Base.shared_connection=ActiveRecord::Base.connection
现在,无论何时运行测试,数据库都将被重置。这来自Aaron Sumner撰写的“使用RSpec进行日常Rails测试”一书
答案 1 :(得分:5)
每个测试都包含在数据库事务中。这意味着测试期间创建的所有内容都应该在测试结束时消失。因此,我怀疑数据库中的任何内容都是在测试之外进行的(例如在before(:all)
块中)。
此外,这并不能保证每次运行测试时数据库都是空的。有可能你不小心意外添加了一条记录,现在它只是不断恢复到那个状态。
如果你想确保你的测试每次都有一个闪亮的数据库,你应该看一下database_cleaner gem。
答案 2 :(得分:1)
最简单的解决方案是确保RSpec测试在事务中运行(Rails默认执行此操作)
spec_helper.rb
config.around(:each) do |example|
ActiveRecord::Base.transaction do
example.run
raise ActiveRecord::Rollback
end
end
答案 3 :(得分:0)
如果我不得不猜测,行post :create, email: alice.email
似乎可能是进行实际用户创建的候选者。
使用虚假测试将该行删除,并查看您是否仍在获取在数据库中创建的用户。