考虑rspec
的以下测试:
class RspecTest
def initialize
end
def to_s
"foo"
end
end
describe RspecTest do
it "should return foo (to_s)" do
RspecTest.new.should == "foo"
end
it "should return foo (inspect)" do
RspecTest.new.inspect == "foo"
end
end
通过rspec
进行测试时:
%: rspec rspec_test.rb
F.
Failures:
1) RspecTest should return foo (to_s)
Failure/Error: RspecTest.new.should == "foo"
expected: "foo"
got: foo (using ==)
Diff:
# ./rspec_test.rb:13:in `block (2 levels) in <top (required)>'
Finished in 0.00059 seconds
2 examples, 1 failure
因此第一次测试失败,而第二次测试通过。那是为什么?
答案 0 :(得分:3)
第二次测试通过,因为它没有测试任何东西。它不包含任何期望(即呼叫should
或should_not
)。 无法失败,因为 无法失败。
第一个测试失败,因为您断言RspecTest
的实例等于字符串'foo'
。这不可能是真的。如果它们甚至不是对象的种那么这两个对象怎么可能是相等的呢?
根据测试描述判断,您实际上并不是要测试RspecTest
的实例是否等于字符串'foo'
,而是测试实例方法的返回值{ {1}}等于字符串to_s
。但是,您永远不会在任何地方拨打'foo'
。
让我们先解决两个明显的问题。现在,我们有这样的测试:
to_s
有两个it 'should return foo (to_s)' do
RspecTest.new.to_s.should == 'foo'
end
it 'should return foo (inspect)' do
RspecTest.new.inspect.should == 'foo'
end
次调用存在一些不必要的重复,所以让我们通过简单地将RspecTest.new
设为默认主题来解决这个问题:
RspecTest.new
实际上,如果你没有提供一个明确的主题,那么RSpec会走向嵌套 subject { RspecTest.new }
it 'should return foo (to_s)' do
subject.to_s.should == 'foo'
end
it 'should return foo (inspect)' do
subject.inspect.should == 'foo'
end
块的链,直到它找到一个类,然后简单地调用该类的describe
方法提供主题。所以,我们可以删除new
声明:
subject
就个人而言,我更喜欢让RSpec自己提供示例名称,以便示例名称和实际示例代码不会失去同步,所以我可能会写得更像这样:
it 'should return foo (to_s)' do
subject.to_s.should == 'foo'
end
it 'should return foo (inspect)' do
subject.inspect.should == 'foo'
end
哪个收益率:
describe RspecTest do
describe '#to_s' do
it { subject.to_s.should == 'foo' }
end
describe '#inspect' do
it { subject.inspect.should == "foo" }
end
end
最后但并非最不重要的是,您的初始化程序实际上并没有执行任何操作,因此您不需要它。总之,我的版本看起来像这样:
RspecTest
#to_s
should == "foo"
#inspect
should == "foo"
Finished in 0.16023 seconds
2 examples, 0 failures
答案 1 :(得分:2)
我认为你的测试应该如下(他们都会通过)。第一个缺少实际的to_s
调用,而第二个调用缺少.should
:
describe RspecTest do
it "should return foo (to_s)" do
RspecTest.new.to_s.should == "foo"
end
it "should return foo (inspect)" do
RspecTest.new.inspect.should == "foo"
end
end