用Rspec绑定File.open
我正在尝试存根File.open以测试我读取CSV文件的方法。
这是模型:
class BatchTask def import(filename) CSV.read(filename, :row_sep => "\r", :col_sep => ",") end end
这是规范代码:
let(:data) { "title\tsurname\tfirstname\rtitle2\tsurname2\tfirstname2\r"} let(:result) {[["title","surname","firstname"],["title2","surname2","firstname2"]] } it "should parse file contents and return a result" do File.stub(:open).with("file_name","rb") { StringIO.new(data) } person.import("file_name").should == result end
但是,当我尝试这样做时,我得到(stacktrace):
Errno::ENOENT in 'BatchTask should parse file contents and return a result' No such file or directory - file_name /Users/me/app/models/batch_task.rb:4:in `import' ./spec/models/batch_task_spec.rb:10: Finished in 0.006032 seconds
我一直在撞击这个,无法弄清楚我做错了什么。 任何帮助将不胜感激!
提供堆栈跟踪会很有帮助,虽然我会猜测它为什么会发生。 另外,我相信你在这里接近并不好,我会详细说明我认为你应该如何测试。
简单地说,我认为CSV.read
不使用File.open
。 它可以使用Kernel#open
或其他各种方式在Ruby中打开文件。 File.open
,你不应该在测试中存根File.open
。
有一本名为“面向测试的成长面向对象软件”的好书,它有一个需要规则:
仅存储您控制的类/接口上的方法
有一个非常简单的原因。 当您进行测试双打(存根)时,主要原因是界面发现 – 您想要弄清楚您的类的界面应该是什么样子,双打为您提供整洁的反馈。 还有一个次要原因 – 在某些情况下(当库不是非常简陋时),存根外部库往往非常棘手。 因此,您可以在这里采取一些不同的方法,我将列举:
- 您可以在集成中进行测试。 您可以在每个测试中创建文件并传递路径名(这很好)。
- 你可以分解你解析的方式。 不是将文件名传递给
CSV.read
,而是在传递打开的File
然后在测试中存根时找到一种方法。 即,让您的代码打开文件而不是CSV
。 这样你就可以轻松地存根 - 改为存根
CSV.read
。 这可能有点引人注目,但实际上,您不是在测试代码,而是在测试CSV
库。 它应该已经有了自己的测试,无论如何你都不需要测试它。 相反,你可以依赖它可以工作的事实,只是将调用存根。
其中,我可能会选择第三个。 我不喜欢在我的unit testing中测试依赖项。 但是,如果你想让你的测试调用该代码,我建议找到一种方法来做第二个选项( CSV.new(file)
应该做的伎俩,但我没有时间去调查)并最终回到#1如果没有其他工作。
- 如何在测试套件中进行下一次测试之前关闭所有窗口?
- RSpec:如何编写unit testing用例来接收在私有方法中引发的exception
- 如何在整个示例组中使用实例变量,即使它在示例之外?
- Rails / rspec:如何在请求规范中设置cookie?
- 使用带有Page-Object的IE 11 x64时出现“Watir :: Exception :: NoMatchingWindowFoundException:浏览器窗口已关闭”错误
- 我应该何时在Cucumber和RSpec工作流程中单独测试视图?
- 反对在RSpec测试中使用之前,之后和主题的论点是什么?
- 太阳黑子和RSpec失败。 提交似乎没有起作用
- 使用Rspec在模型中测试关系和方法