首页 > 解决方案 > 如何在 case 语句中存根\模拟实例?

问题描述

我有一个类方法,它使用另一个类实例方法:

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

标签: rubyrspec

解决方案


Case 语句===用于大小写相等的目的,在这种情况下Foo是接收者而不是参数。例如

  case attr
    when Foo then attr.foo
  end 

相比之下attrFoo反之亦然Foo === attr

所以你可以改变你的测试

it 'make some business logic here' do
  allow(Foo).to receive(:===).with(foo).and_return(true)
  expect { subject }.to be_truthy
end

This way when it evaluates your case statement it will follow the when Foo path because Foo === attr will be true due to the stubbing.


推荐阅读