测试时我应该在 Factory Girl 中还是在规范文件中存根模型吗?

发布于 2025-01-01 05:16:08 字数 601 浏览 1 评论 0原文

几乎我遇到的每个规范文件最终都会写这样的内容:

  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 获得的模型是完全有效的。但是,如果我不存根这些东西,它会将内容保存在文件系统中,并验证我没有测试的东西...

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

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

如果工厂内的存根是均匀的可能的。

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

Almost every spec file I come accross I end up writing stuff like:

  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

I mean, the model I get from Factory.build is completely valid. But if I don't stub that stuff it saves things in the filesystem, and validates stuff I'm not testing...

What I mean, I think it would be cleaner to do something like this:

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

If stubbing within the Factory is even possible.

What is the proper way to stub the model?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

等待圉鍢 2025-01-08 05:16:08

@fkreusch 的答案非常有效,直到您使用新的 RSpec expect() 语法 (3.0+)

将其放入 rails_helper.rb 对我有用:

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

在OP的示例中,您可以现在做:

FactoryBot.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_bot/issues/703#issuecomment-83960003< /a>

@fkreusch's answer works great until you use the new RSpec expect() syntax (3.0+)

Putting this into rails_helper.rb works for me:

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

In the OP's example, you can now do:

FactoryBot.define do
  factory :cimg_for_testing_tags do

    ... # Factory attributes

    after(:build) do |cimg|
      allow(cimg).to receive(:validate_img) { true }
    end
  end
end

Credit: github.com/printercu, see: https://github.com/thoughtbot/factory_bot/issues/703#issuecomment-83960003

無處可尋 2025-01-08 05:16:08

在最近版本的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

In recent versions of factory_girl you have an after_build callback, so I believe you could define your factory like this:

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

After factory_girl 3.3.0, the syntax has changed to following:

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
我不吻晚风 2025-01-08 05:16:08

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

您可以这样做

let(:user) instance_double(User, FactoryGirl.attributes_for(:user))

before do
  allow(user).to receive(:something).and_return('something')
end

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

A factory should produce "real world" objects therefore it's a bad practice (and error prone) to change behaviour (i.e. stub) in a factory.

You can do

let(:user) instance_double(User, FactoryGirl.attributes_for(:user))

before do
  allow(user).to receive(:something).and_return('something')
end

and if your before clause gets too big you may want to extract it to a separate method or create a mock child class that overrides methods you want to stub.

愁杀 2025-01-08 05:16:08

您还可以考虑使用 FactoryGirl#build_stubbed

You might also consider using FactoryGirl#build_stubbed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文