我想在" POODR"中翻译Sandi Metz的最终测试代码。从Minitest到RSpec。在第9章中,她检查是否有任何对象包含DiameterizableInterfaceTest"有一个"直径"方法。在这里,它检查DiameterDouble和Wheel是否具有"直径"方法:
module DiameterizableInterfaceTest
def test_implements_the_diameterizable_interface
assert_respond_to(@object, :diameter)
end
end
class DiameterDouble
def diameter
10
end
end
class DiameterDoubleTest < MiniTest::Test
include DiameterizableInterfaceTest
def setup
@object = DiameterDouble.new
end
end
class WheelTest < MiniTest::Test
include DiameterizableInterfaceTest
def setup
@wheel = @object = Wheel.new(26, 1.5)
end
def test_calculates_diameter
assert_in_delta(29,
@wheel.diameter,
0.01)
end
end
这很有效。只有那一行,&#34;包括DiameterizableInterfaceTest,&#34;可以。但是,我不能在RSpec中做同样的事情。我试过了:
module DiameterizableInterfaceTest
describe 'object has diameter method' do
it 'implements diameterizable interface' do
expect(object).to respond_to(:diameter)
end
end
end
class DiameterDouble
def diameter
10
end
end
describe DiameterDouble do
include DiameterizableInterfaceTest
let (:object) { DiameterDouble.new }
end
但&#34;对象&#34;的所有组合在模块中失败。如果我使用&#34; object,&#34;它说&#34;未定义的局部变量或方法`对象&#39;。&#34;对于&#34; @object,&#34;它表示&#34;预计无响应:直径。&#34;对于&#34;:对象,&#34;它说&#34;期望:反对的对象:直径。&#34;
要在RSpec中包含该模块,唯一有效的是如果我更改&#34;描述&#34;阻止一个方法,像这样。这迫使我为&#34; has_diameter_method?&#34;添加一个it-block。对于我检查的每个班级,这是荒谬和罗嗦的:
module DiameterizableInterfaceTest
def has_diameter_method?
expect(@object).to respond_to(:diameter)
end
end
class DiameterDouble
def diameter
10
end
end
describe DiameterDouble do
include DiameterizableInterfaceTest
before do
@object = DiameterDouble.new
end
it 'has diameter method' do
has_diameter_method?
end
end
describe Wheel do
include DiameterizableInterfaceTest
describe '#diameter' do
before do
@wheel = @object = Wheel.new(26, 1.5)
end
it 'calculates diameter' do
expect(@wheel.diameter).to eq(29)
end
it 'has diameter method' do
has_diameter_method?
end
end
end
我如何在RSpec中的多个类测试中包含模块,就像我在Minitest中所做的那样,而不添加额外的it-block?在Minitest中,我可以为每个类添加1行检查,&#34;包括DiameterizableInterfaceTest。&#34;在RSpec中,还需要4行。
这是我想要做的another example。它在Minitest中很容易,但在RSpec中却不容易。
答案 0 :(得分:2)
我想出了答案!谢谢,CodeSchool:http://rspec.codeschool.com/levels/4/challenges/4
我的RSpec解决方案:https://github.com/rayning0/poodr/blob/master/spec/ch9g_spec.rb
关键是使用shared_examples
,它允许使用通用对象(&#34;它&#34;)。在测试中,我使用it_behaves_like
检查shared_examples中的所有行为。另外,对于Wheel,我需要添加subject { wheel }
,或者说ArgumentError: wrong number of arguments (0 for 2)
。
shared_examples 'Diameterizable' do
it { should respond_to(:diameter) }
end
class DiameterDouble
def diameter
10
end
end
describe DiameterDouble do
it_behaves_like 'Diameterizable'
let(:object) { DiameterDouble.new }
end
describe Wheel do
it_behaves_like 'Diameterizable'
let(:wheel) { Wheel.new(26, 1.5) }
subject { wheel }
it 'calculates diameter' do
expect(wheel.diameter).to eq(29)
end
end
答案 1 :(得分:0)
看看rspec&#34;共享示例&#34;:https://www.relishapp.com/rspec/rspec-core/docs/example-groups/shared-examples