ruby on rails - RSpec:在每个上下文之后刷新表/销毁对象



如何删除创建的对象(数据库中的和内存中的)

  • 每次测试后
  • 和每个上下文之后?(在一个上下文中,在彼此之间构建测试是有意义的)

是否有自动执行此操作的方法?

我有以下问题:

每个测试将条目保存到数据库中。接下来的测试依赖于这些条目。即使我想构建依赖于其他测试的测试,我也不能,因为测试执行的顺序是不可控制的。

factories.rb:

sequence(:name) { |n| "purchaser #{n}" }      

organization_spec.rb:

context "when no supplier exists" do
  it "finds no associated suppliers" do
    purchaser = create(:organization_purchaser)                
    purchaser.partners.empty?.should == true
  end
end
context "when one supplier exists" do
  it "finds one associated suppliers" do
    purchaser = create(:organization_purchaser)      
    supplier = create(:organization_supplier)
    partnership = create(:partnership, organization: purchaser, partner: supplier)         
    purchaser.partners.last.name.should == "purchaser 1"
  end
end
context "when two suppliers exist" do        
  it "finds two associated suppliers" do
    purchaser = create(:organization_purchaser)      
    2.times do |i|
      supplier = create(:organization_supplier)
      partnership = create(:partnership, organization: purchaser, partner: supplier) 
    end    
    purchaser.partners.last.name.should == "purchaser 2"
  end
end

RSpec输出:

Organization
  #suppliers_for_purchaser
    responds
    when no supplier exists
      finds no associated suppliers
    when two suppliers exist
      finds two associated suppliers
    when one supplier exists
      finds one associated suppliers (FAILED - 1)
Failures:
1) Organization#suppliers_for_purchaser when one supplier exists finds one associated suppliers
 Failure/Error: purchaser.partners.last.name.should == "purchaser 1"
   expected: "purchaser 1"
        got: "purchaser 3" (using ==)

你应该使用Database Cleaner

您所要做的就是将以下代码添加到您的Rspec配置文件spec_helper.rb

config.before(:suite) do
  DatabaseCleaner.strategy = :transaction
  DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
  DatabaseCleaner.start
end
config.after(:each) do
  DatabaseCleaner.clean
end

从Rails 5.1开始,如果您使用config.use_transactional_tests

,则不需要此操作。https://github.com/rails/rails/pull/19282

是否尝试添加before方法?

describe MyController do
before(:each) do
  User.delete_all
  MyOtherModel.delete_all
  ...
end

我认为你的问题更像是我如何重置工厂女孩序列?那些不存储在数据库中,即使你删除所有你仍然会有问题。当测试这样的东西时,我发现它更容易覆盖工厂女孩序列..

it "finds one associated suppliers" do
    purchaser = create(:organization_purchaser)      
    supplier = create(:organization_supplier , name: "My First Supplier")
    partnership = create(:partnership, organization: purchaser, partner: supplier)         
    purchaser.partners.last.name.should == "My First Supplier"
  end

你可能做的其他事情是像

it "finds one associated suppliers" do
        purchaser = create(:organization_purchaser)      
        supplier = create(:organization_supplier)
        partnership = create(:partnership, organization: purchaser, partner: supplier)         
        purchaser.partners.last.should == supplier 
      end

或者

it "finds one associated suppliers" do
        purchaser = create(:organization_purchaser)      
        supplier = create(:organization_supplier)
        partnership = create(:partnership, organization: purchaser, partner: supplier)         
        purchaser.partners.last.name.should == supplier.name
      end

最新更新