断言在模拟上没有调用任何方法

jhw*_*ist 4 ruby rspec rspec2

我正在使用Flexmock模拟框架用Rspec2编写测试.我希望我的一种方法可以缓存结果,并希望用我的模拟验证这一点.

describe SomeClass do
  before do
    @mock = flexmock()
  end

  after do
    @mock.flexmock_verify()
  end

  it "method caches results"
    c = SomeClass.new(@mock)
    c.method
    @mock.should_receive(:expensive_method).never
    c.method.should == ['A']
  end
end
Run Code Online (Sandbox Code Playgroud)

如果我想确保:expensive_method永远不会被调用,这种方法很有效.但是,我希望我的类能够在:method不调用传入(模拟)类的情况下执行任何操作.有没有办法表达这个?

背景:在我的例子中,注入的类执行昂贵的操作,因此应该为相同的查询缓存结果.

更新
感谢到目前为止的建议,也许我只是假设错误或者我想要的甚至没有意义.我实现缓存的方法是将一个类变量放入SomeClass并添加到:method:

def SomeClass
  @@cache_map = {}

  def method
    # extract key
    return @@cache_map[key] if @@cache_map.has_key?(key)
    # call :expensive_method to get result
    @@cache_map[key] = result
    return result
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,为了测试正确的缓存,我必须:extensive_method至少调用一次来加载缓存.我喜欢David Chelimsky的解决方案,但它没有回答我的原始意图,即:测试在第一次调用SomeClass.method注入类之后再也没有调用(既不是:expensive_method也不是其他).

Dav*_*sky 9

指定缓存的传统方法是@mock.should_receive(:expensive_method).once在调用之前说method,然后调用调用它两次的方法.

我还想为此使用两个示例:一个用于指定它如何使用数据,一个用于指定它仅检索一次数据:

describe Client do
  let(:service) { flexmock() }
  let(:client)  { Client.new(service) }

  it "uses data retrieved from service" do
    service.stub(:expensive_method).and_return('some data')
    client.method.should eq('some data')
  end

  it "only retrieves the data once" do
    service.should_receive(:expensive_method).once
    client.method
    client.method
  end
end
Run Code Online (Sandbox Code Playgroud)

此外,您无需调用flexmock_verify,因为这是自动发生的.