[英]Ruby inspect vs to_s in Rspec
考慮對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
因此,第一個測試失敗,而第二個測試通過。 這是為什么?
第二個測試通過了,因為它沒有測試任何東西。 它不包含任何期望(即,對should
或should_not
的調用)。 它不會失敗,因為沒有什么可以失敗的。
第一次測試失敗,因為您斷言RspecTest
的實例等於字符串'foo'
。 這不可能是真的。 如果這兩個對象不是同一種對象,怎么可能相等?
從測試的描述來看,您實際上並不是要測試RspecTest
的實例是否等於字符串'foo'
,而是要測試實例方法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
為默認主題來解決此問題:
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
實際上,如果您不提供明確的主題,則RSpec將沿着嵌套的describe
塊的鏈向上移動,直到找到一個類為止,並且將僅調用該類的new
方法來提供主題。 因此,我們可以刪除subject
聲明:
it 'should return foo (to_s)' do
subject.to_s.should == 'foo'
end
it 'should return foo (inspect)' do
subject.inspect.should == 'foo'
end
就個人而言,我更喜歡讓RSpec自己提供示例名稱,以免示例名稱和實際示例代碼不同步,因此,我可能會這樣寫:
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
最后但並非最不重要的一點是,您的初始化程序實際上並未執行任何操作,因此您不需要它。 總之,我的版本如下所示:
class RspecTest
def to_s; 'foo' end
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
我認為您的測試應如下(它們都將通過)。 第一個缺少實際的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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.