2

我有一个带有以下方法的愚蠢的“队列类 [1]”,我想用 Rspec 来指定。我对测试写入文件系统是否有效(它有效,我的计算机有效)不感兴趣,而是对正确的数据是否被写掉感兴趣。

def write transaction
  File.open("messages/#{@next_id}", "w") {|f| f.puts transaction }
  @next_id += 1
end

测试的规范是:

describe TransactionQueue do
  context "#write" do
    it "should write positive values" do
      open_file = mock File
      open_file.stub(:puts)

      File.any_instance.stub(:open).and_yield(open_file)
      File.any_instance.should_receive(:open)
      open_file.should_receive(:puts).with("+100")

      @queue = TransactionQueue.new
      @queue.write("+100")
    end
  end
end

运行此程序失败,因为我的 Mocks 从未收到预期的“打开”和“放置”消息。

我可以这样嘲笑File吗?我使用any_instance正确吗?我尝试存根“块收益”是否正确?

如果可以避免,我宁愿不使用像 FakeFS 这样的额外 gem;这与其说是让它发挥作用;bu主要是关于实际了解正在发生的事情。因此,我试图避免额外的宝石/复杂层。

[1] 课程来自The Cucumber Book;但这些测试与 Cucumber 本身无关。我在看书时不知何故破坏了代码;并想通过为本书未编写测试的部分编写单元测试来找出什么:辅助类。

4

1 回答 1

5

File它不是您期望接收该open方法的类的“任何实例” ;它是File类本身:

  File.stub(:open).and_yield(open_file)
  File.should_receive(:open)

此外,不要同时使用存根和期望。如果要验证File.open实际调用的是:

  File.should_receive(:open).and_yield(open_file)

如果您只想存根open方法以防它被调用,但不想要求它作为@queue.write方法的行为:

  File.stub(:open).and_yield(open_file)

(这是凭记忆,几个月没用RSpec了。)

于 2012-12-29T12:17:23.183 回答