Ruby中的stubbing和mocking

时间:2014-03-17 15:02:07

标签: ruby unit-testing rspec stub

我想我明白这是在进行,但我想确定。

有些代码需要使用文件方法进行单元测试:

temp = File.new(uri.path)
@path = Rails.root.to_s + "/tmp/" +uri.path.split("/").last
File.open(@path, "w"){|f| f.write(temp.read)} if File.exists(temp)
temp.close

单元测试有:

file = mock(File)
File.stub(:new).and_return(file)
File.stub(:open).and_return(file)
file.stub(:close)

我猜测File.stubfile.stub之间的区别在于File.stub会在File类上存根方法,而file.stubfile是模拟File对象)将在File对象上存根任何方法吗?

2 个答案:

答案 0 :(得分:2)

调用stub(:method)将在您调用它的对象上存根方法。所以你对File.stub(:new)的调用会将对File.new(类方法)的所有调用都存根。对file.stub(:close)的调用会将所有调用存根到file.close,但仅存在于您调用存根的实例上

如果要将对所有File实例的所有调用存根,您可以:

  1. 使用any_instance
  2. 或者您可以将File.new存根为仅使其返回带有存根关闭的文件对象,就像您一样:

    File.stub(:new).and_return(file)
    File.stub(:open).and_return(file)
    
  3. 请注意,在案例2中,每次调用File.new后都会返回相同的实例。如果不是您想要的,您可以随时将一个块交给存根,在那里您可以为存根的元数据提供substitute

答案 1 :(得分:1)

您的理解是正确的。

File.stub(:new)

在类new

上存根调用File
file.stub(:close)

close对象

上存根调用file

在您的情况下,您也可以

file = mock(File, :close => nil) #this will create a mocked object that responds with nil when close is called