【问题标题】:Issue with testing Tempfile in ruby在 ruby​​ 中测试 Tempfile 的问题
【发布时间】:2014-12-04 09:34:39
【问题描述】:

我有一段代码可以创建临时文件

@tmp_file = Tempfile.new("filename")

创建后我将它们关闭,

@tmp_file.close unless @tmp_file.closed?

当需要向临时文件添加数据时,我会打开它们并添加数据,如下所示

   def add_row_to_file(row)
      @tmp_file.open
      @tmp_file.read
      @tmp_file.print(row.to_json + "\n")
    end

一切都很好,但是为了测试同样的内容,我将临时文件存根如下,并且当测试用例遇到 add_row_to_file(row) 时会产生错误

  buffers = {}

  Tempfile.stub(:new) do |file_name|
    buffer = StringIO.new
    buffers[file_name] = buffer
  end

错误信息是:

Failure/Error: ]],
 NoMethodError:
   private method `open' called for #<StringIO:0x00000010b867c0>

我想在创建时保持临时文件关闭,因为在操作系统级别存在最大临时文件打开问题(我必须处理将大量临时文件上传到 S3) 但是为了测试,我在访问 StringIO 的私有方法时遇到了问题。

知道如何解决这个问题吗?谢谢。

我有一个解决方法,即在测试环境中跳过关闭 StringIO。

@tmp_file.close unless @tmp_file.closed? || Rails.env.test?

并更新add_row_to_file(row)如下

   def add_row_to_file(row)
      @tmp_file.open unless Rails.env.test?
      @tmp_file.read unless Rails.env.test?
      @tmp_file.print(row.to_json + "\n")
    end

【问题讨论】:

  • 你为什么不存根Tempfile#open
  • strong 没有 open 方法(所以你实际上是在调用 Kernel#open)
  • 我同意@mudasobwa。不要存根new 并且不要测试读取文件的行为,这不是你的情况。从您的应用程序的角度测试这里的重要内容。如果您需要一些输入数据,请在测试中伪造它。
  • @SantoshSindham 我看到你需要一些过度的方法来进行测试,但要调用方法 open 只需使用 @tmp_file.send(:open)
  • 只使用一个选择器:args = [ :open ]; args &lt;&lt; m if m.is_a? (File) ; k.send *args

标签: ruby-on-rails ruby temporary-files


【解决方案1】:

如果我们希望在测试中实现 100% 的代码覆盖率,除了提供的解决方法之外,我们还可以尝试以下方法。

如果是StringIO,不要关闭流

@tmp_file.close unless @tmp_file.is_a?(StringIO)

所以我们不需要在测试时打开它。

    def add_row_to_file(row)
      @tmp_file = File.open(@tmp_file, 'a+') unless @tmp_file.is_a?(StringIO)
      @tmp_file.print(row.to_json + "\n")
    end

通过这种方式,我们可以在测试环境中实现 Tempfile 测试,而无需实际创建文件,并且在测试时具有 100% 的代码覆盖率。

【讨论】:

    猜你喜欢
    • 2011-04-05
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 2013-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多