简体   繁体   English

为什么“不要在诸如`before`之类的钩子中使用`expect`”?

[英]Why "Do not use `expect` in hooks such as `before`"?

My question is pretty much explained by the title.我的问题几乎可以通过标题来解释。 I was trying to google it but did not find anything satisfying at all.我试图用谷歌搜索它,但根本没有找到任何令人满意的东西。 rubocop-rspec does not allow expect inside before , why is that? rubocop-rspec before不允许在里面使用expect ,这是为什么? Is there a good reason to avoid such a usage?是否有充分的理由避免这种用法? Thanks for your explanations in advance!感谢您提前的解释!

Four phase test is a testing pattern commonly used for unit tests.四阶段测试是单元测试常用的一种测试模式。 It's general form:它的一般形式:

test do
  setup
  exercise
  verify
  teardown
end

before is part of the setup phase where the developer creates the scenario and supporting data. before是开发人员创建场景和支持数据的setup阶段的一部分。

expect is part of the verify phase, which happens inside a it block. expectverify阶段的一部分,它发生在it块内。

A common pattern is to use allow in before blocks and use expect in it blocks for example.例如,一个常见的模式是beforebefore使用allow并在it块中使用expect

RSpec.describe User do
  describe '#forgot_password' do
    before { allow(EmailService).to receive(:send) }

    subject { FactoryBot.create(:user).forgot_password }

    it 'sends an email to user to start the password resetting process' do
      subject
      expect(EmailService).to have_received(:send).with(...)
    end
  end
end

before blocks can also be added in other layers of the application ( spec_helper.rb , shared examples) and one does not want to rely on the correct order of before blocks in order for a test to be successful. before块也可以添加到应用程序的其他层( spec_helper.rb ,共享示例),并且不想依赖 before 块的正确顺序来使测试成功。

Only tests should include expectations (also known as assertions).只有测试应该包括期望(也称为断言)。 before blocks are meant to configure the environment in which your tests run. before块用于配置测试运行的环境。 They are not meant to be tests themselves.它们本身并不意味着测试。

I agree with expects in before filters since you are not changing anything in the examples, you are always testing the general setup, but in after filters I do not see a reason to avoid expectations.我同意before过滤器before期望,因为您没有在示例中更改任何内容,您总是在测试一般设置,但在过滤器after我没有看到避免期望的理由。

When writing tests, context is what matters most, you are testing the same code under different parameters (or contexts), hence, the examples need only to modify the context and the assertion could remain constant.在编写测试时,上下文是最重要的,您在不同的参数(或上下文)下测试相同的代码,因此,示例只需要修改上下文,断言可以保持不变。

See this example:看这个例子:

 RSpec.describe Foo do
  subject { create(:foo) }

  describe 'some_method' do
    let(:foo) { create(:foo) }

    after do
      foo.update_rate
      subject.update_rate

      expect(foo.rate).to be > subject.rate
    end

    it 'gives higher rates to foos with more reviews if all are positive' do
      foo.update!(votes_up_count: 10, reviews_count: 10)
      subject.update!(votes_up_count: 1, reviews_count: 1)
    end

    it 'gives higher rates to foos with less positive reviews and no negative reviews' do
      foo.update!(votes_up_count: 4, reviews_count: 4)
      subject.update!(votes_up_count: 5, reviews_count: 6)
    end
  end
end

As opposed to

 RSpec.describe Foo do
  subject { create(:foo) }

  describe 'some_method' do
    let(:foo) { create(:foo) }

    it 'gives higher rates to foos with more reviews if all are positive' do
      foo.update!(votes_up_count: 10, reviews_count: 10)
      subject.update!(votes_up_count: 1, reviews_count: 1)

      foo.update_rate
      subject.update_rate

      expect(foo.rate).to be > subject.rate
    end

    it 'gives higher rates to foos with less positive reviews and no negative reviews' do
      foo.update!(votes_up_count: 4, reviews_count: 4)
      subject.update!(votes_up_count: 5, reviews_count: 6)

      foo.update_rate
      subject.update_rate

      expect(foo.rate).to be > subject.rate
    end
  end
end

So I would not take this cop as gospel to be honest, i think it goes against good testing practices.所以说实话,我不会把这个警察当作福音,我认为这违背了良好的测试实践。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM