我有一个类方法,它使用另一种类实例方法:
class Foo
def foo
# a lot of code here, which return String instance
end
end
class Bar
class UnknownType < StandardError;end
def initialize(foo)
self.foo = foo
end
attr_reader :foo
def call
# some code which use method foo
foo
end
private
def foo=(attr)
@foo ||= case attr
when Foo then attr.foo
when String then attr
else raise UnknownType, "Unknown type #{attr.class.name}"
end
end
end
我的测试不起作用,我尝试使用子方法: -is_a -kind_of?
let(:foo) { instance_double(Foo, foo: 'some text') }
let(:bar) { Bar.new(foo) }
subject { bar.call }
it 'make some business logic here' do
expect { subject }.to be_truthy
end
但是它会引发错误UnknownType
,因为模板是#<InstanceDouble(Foo) (anonymous)>
不是Foo
答案 0 :(得分:1)
case语句将===
用于大小写相等,在这种情况下,Foo
是接收者而不是参数。例如
case attr
when Foo then attr.foo
end
将attr
与Foo
比较为Foo === attr
,而不是相反。
因此您可以将测试更改为
it 'make some business logic here' do
allow(Foo).to receive(:===).with(foo).and_return(true)
expect { subject }.to be_truthy
end
这样,在评估您的case语句时,它将遵循when Foo
路径,因为Foo === attr
由于存根而为true。
答案 1 :(得分:0)
instance_double(Foo).class != Foo
。如您所见,这将返回一个InstanceDouble对象,该对象将无法用于比较。
我将用手动实例化和存根替换您的instance_double行:
let(:foo) do
foo = Foo.new
allow(foo).to receive(:foo).and_return "some text"
foo
end
let(:bar) { Bar.new(foo) }
那样foo.class == Foo
,它将在您的case语句中正常工作。