[英]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. expect
是verify
阶段的一部分,它发生在it
块内。
A common pattern is to use allow
in before
blocks and use expect
in it
blocks for example.例如,一个常见的模式是before
块before
使用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.