[英]Ruby inspect vs to_s in Rspec
Consider the following test for 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
And when tested through rspec
: 当通过
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
So the first test fails, whereas the second test passes. 因此,第一个测试失败,而第二个测试通过。 Why is that?
这是为什么?
The second test passes, because it doesn't test anything. 第二个测试通过了,因为它没有测试任何东西。 It doesn't contain any expectation (ie a call to
should
or should_not
). 它不包含任何期望(即,对
should
或should_not
的调用)。 It cannot fail, because there is nothing to fail. 它不会失败,因为没有什么可以失败的。
The first test fails, because you are asserting that an instance of RspecTest
is equal to the string 'foo'
. 第一次测试失败,因为您断言
RspecTest
的实例等于字符串'foo'
。 This cannot possibly be true. 这不可能是真的。 How could those two objects possibly be equal if they aren't even the same kind of object?
如果这两个对象不是同一种对象,怎么可能相等?
Judging by the description of the test, you didn't actually mean to test whether the instance of RspecTest
is equal to the string 'foo'
, but rather whether the return value of the instance method to_s
is equal to the string 'foo'
. 从测试的描述来看,您实际上并不是要测试
RspecTest
的实例是否等于字符串'foo'
,而是要测试实例方法to_s
的返回值是否等于字符串'foo'
。 However, you never call to_s
anywhere. 但是,您永远不会在任何地方调用
to_s
。
Let's first fix the two obvious problems. 让我们首先解决两个明显的问题。 Now, we have a test like this:
现在,我们进行如下测试:
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
There is some unnecessary duplication there with the two RspecTest.new
calls, so let's fix that by simply making RspecTest.new
the default subject: 这两个
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
And actually, if you don't supply an explicit subject, then RSpec will walk up the chain of nested describe
blocks until it finds a class, and will simply call that class's new
method to provide the subject. 实际上,如果您不提供明确的主题,则RSpec将沿着嵌套的
describe
块的链向上移动,直到找到一个类为止,并且将仅调用该类的new
方法来提供主题。 So, we can just delete the subject
declaration: 因此,我们可以删除
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
Personally, I prefer to let RSpec provide the example name by itself, so that the example name and the actual example code don't get out of sync, so I'd probably write that more like this: 就个人而言,我更喜欢让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
Which yields: 产生:
RspecTest
#to_s
should == "foo"
#inspect
should == "foo"
Finished in 0.16023 seconds
2 examples, 0 failures
Last but not least, your initializer isn't actually doing anything, so you don't need it. 最后但并非最不重要的一点是,您的初始化程序实际上并未执行任何操作,因此您不需要它。 All together, my version looks like this:
总之,我的版本如下所示:
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
I think your test should be the following (and they'll both pass). 我认为您的测试应如下(它们都将通过)。 The first one is missing the actual
to_s
call, and the seocnd one is missing the .should
: 第一个缺少实际的
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.