我应该在测试时在Factory girl或spec文件中存根模型吗?

几乎每一个我遇到的spec文件最终都会写出如下内容:

before :each do @cimg = Factory.build :cimg_valid @cimg.stub(:validate_img).and_return true @cimg.stub(:validate_img_url).and_return true @cimg.stub(:save_images).and_return true @cimg.stub(:process_image).and_return true @cimg.stub(:img).and_return true end 

我的意思是,我从Factory.build获得的模型是完全有效的。 但是,如果我不存储那些东西,它会保存文件系统中的东西,并validation我没有测试的东西……

我的意思是,我认为做这样的事情会更干净:

  before :each do @cimg = Factory.build :cimg_for_testing_tags end 

如果甚至可以在工厂内进行存根。

存根模型的正确方法是什么?

在factory_girl的最新版本中,你有一个after_build回调,所以我相信你可以像这样定义你的工厂:

 FactoryGirl.define do factory :cimg_for_testing_tags do ... # Factory attributes after_build do |cimg| cimg.stub(:validate_img).and_return true end end end 

UPDATE

在factory_girl 3.3.0之后,语法已更改为以下内容:

 FactoryGirl.define do factory :cimg_for_testing_tags do ... # Factory attributes after(:build) do |cimg| cimg.stub(:validate_img).and_return true end end end 

@fkreusch的答案很有用,直到你使用新的RSpec expect()语法(3.0+)

将它放入rails_helper.rb对我rails_helper.rb

 FactoryGirl::SyntaxRunner.class_eval do include RSpec::Mocks::ExampleMethods end 

在OP的示例中,您现在可以执行以下操作:

 FactoryGirl.define do factory :cimg_for_testing_tags do ... # Factory attributes after(:build) do |cimg| allow(cimg).to receive(:validate_img) { true } end end end 

图片来源:github.com/printercu,请参阅: https : //github.com/thoughtbot/factory_girl/issues/703#issuecomment-83960003

您也可以考虑使用FactoryGirl#build_stubbed 。

工厂应该生成“真实世界”的对象,因此在工厂中改变行为(即存根)是一种不好的做法(并且容易出错)。

你可以做

 let(:user) instance_double(User, FactoryGirl.attributes_for(:user)) before do allow(user).to receive(:something).and_return('something') end 

如果你的before子句太大,你可能想要将它提取到一个单独的方法或创建一个模拟子类来覆盖你想要存根的方法。