模拟文件输入作为Rspec上的文件路径

时间:2013-01-23 21:25:41

标签: ruby testing rspec mocking sinatra

我有一个关于如何使用rspec来模拟文件输入的问题。我有一个类的以下代码,但不完全知道模拟文件输入的原因。 filepath/path/to/the/file

我在Google上进行了搜索,结果通常是加载实际文件而不是模拟,但我实际上看起来相反只是模拟,但没有使用实际文件。

module Service
  class Signing
    def initialize(filepath)
      @config = YAML.load_file(filepath)
      raise "Missing config file." if @config.nil?
    end

    def sign()      …
    end

    private
    def which()     …
    end

  end 
end

是否可以使用EOF分隔符进行此文件输入模拟?

file =  <<EOF
A_NAME: ABC
A_ALIAS: my_alias
EOF

2 个答案:

答案 0 :(得分:4)

您可以存根YAML.load_file并从文本中返回已解析的YAML,如下所示:

yaml_text = <<-EOF
  A_NAME: ABC
  A_ALIAS: my_alias
EOF
yaml = YAML.load(yaml_text)
filepath = "bogus_filename.yml"
YAML.stub(:load_file).with(filepath).and_return(yaml)

这并没有完全隐藏文件加载本身,但要做到这一点,你必须假设YAML.load_file在幕后做了什么,这不是一个好主意。由于可以安全地假设已经测试了YAML实现,因此您可以使用上面的代码将整个调用替换为从文本解析的夹具。

如果要测试将正确的文件名传递给load_file,请将存根替换为期望值:

YAML.should_receive(:load_file).with(filepath).and_return(yaml)

答案 1 :(得分:1)

如果想要对某些事情抱有期望,我认为这种调用YAML.load伪造回报的方法并没有太大的好处。 YAML.load_file实际上返回一个哈希值,所以我的建议不是简单地返回一个哈希值,而是完成所有操作:

parsed_yaml = { 
  "somekey" => {
    "someotherkey" => "abc"
  } 
}

YAML.should_receive(:load_file).with(filepath).and_return(parsed_yaml)

由于这应该是一个单元测试而不是集成测试,我认为这会更有意义。