一个rspec it子句中的多个应该声明 - 坏主意?

ezu*_*zuk 16 rspec ruby-on-rails

这是我的rspec测试:

it "can release an idea" do
  james.claim(si_title)
  james.release(si_title)
  james.ideas.size.should eq 0
  si_title.status.should eq "available"
end
Run Code Online (Sandbox Code Playgroud)

最后两条should线路是不是很糟糕?我在某个地方读到你应该只测试每个it块一件事,但是为了确保标题状态发生变化而进行整个测试似乎很愚蠢(同样的功能在我的代码中做了两件事).

Fre*_*ung 22

我对此的解释并不是说should每个规范应该只有一个断言/调用,但每个规范应该只测试一点行为,例如

it 'should do foo and bar' do
  subject.do_foo.should be_true
  subject.do_bar.should be_true
end
Run Code Online (Sandbox Code Playgroud)

很糟糕 - 你同时指出了两种不同的行为.

另一方面,如果你的两个断言只是验证一件事的不同方面,那么我就可以了

it 'should return a prime integer' do
  result = subject.do_x
  result.should be_a(Integer)
  result.foo.should be_prime
end
Run Code Online (Sandbox Code Playgroud)

对我来说,有一个规范检查它返回一个整数和一个单独的返回一个素数的规范是没有多大意义的.

当然在这种情况下,be_prime匹配器可以很容易地进行这两种检查 - 也许一个好的经验法则是,如果你可以使用自定义匹配器明智地将它们减少到1,那么多个断言就可以了(实际上这样做实际上是否值得)取决于你的情况)

在您的特定情况下,可以认为有两种行为在起作用 - 一种是改变状态,另一种是改变ideas收集.我会改写你的规范来说明发布方法应该做什么 -

it 'should change the status to available'
it 'should remove the idea from the claimants ideas'
Run Code Online (Sandbox Code Playgroud)

目前这些事情总是同时发生,但我认为它们是不同的行为 - 你可以很容易地想象一个系统,多个人可以声称/发布一个想法,而状态只有在最后一个人发布想法时才会改变.