如何在 case 语句中 stub\mock 实例?
How to stub\mock instance in case statement?
我有一个 class 方法,它使用另一个 class 实例方法:
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
instance_double(Foo).class != Foo
。如您所见,returns 一个 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 语句使用 ===
来实现大小写相等的目的,在这种情况下 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
由于存根而为真。
我有一个 class 方法,它使用另一个 class 实例方法:
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
instance_double(Foo).class != Foo
。如您所见,returns 一个 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 语句使用 ===
来实现大小写相等的目的,在这种情况下 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
由于存根而为真。