【问题标题】:How to mock Kernel.open or open-uri without calling Kernel explicitly?如何在不显式调用内核的情况下模拟 Kernel.open 或 open-uri?
【发布时间】:2012-12-04 00:17:11
【问题描述】:

如何在 RSpec 中模拟这个调用?

require 'open-uri'
class FileFoo < ActiveRecord::Base
  def download image_url
    open("tmp/#{file}", 'wb') do |file|
      file << open(image_url).read
    end
  end
end

尝试模拟 FileFoo.open,但这不起作用,因为我使用的是下载的文件,而不是返回值。

将代码更改为file &lt;&lt; Kernel.open(image_url).read,并使用以下代码:

Kernel.stub_chain(:open, :read).and_return(File.read image_fixture)

这很好用,但有没有办法模拟Kernel.open().read,而不显式调用内核?

【问题讨论】:

    标签: ruby rspec mocking tdd open-uri


    【解决方案1】:

    通常我认为在这种情况下更好的测试不是模拟特定的文件系统调用,而是使用像 fakefs 这样的 gem 来存根文件系统。

    我在一篇名为 Fake It! 的博文中对此进行了详细讨论。

    这个想法是存根特定的文件系统调用非常脆弱,但是在单元测试中也不一定需要写入实际的文件系统。很多时候,像 fakefs 这样的东西是一种不错的快乐媒介。

    【讨论】:

      【解决方案2】:

      我认为这很困难,因为方法download 的设计很差。它正在做两件事:

      1. 通过 HTTP 获取文件
      2. 将其保存到磁盘

      这些单独的函数都应该被测试,第一个应该被模拟。我认为没有任何理由模拟文件系统,因为保存文件(很小)是快速且易于测试的。

      如果方法被分成2个方法,那么:

      1. fetch with http 会返回文件。
      2. save file 会保存它。

      这种方法使模拟和测试变得简单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-31
        • 2014-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多