【问题标题】:Why would using File.open call once result in it being called 3 times according to rspec为什么根据 rspec 使用 File.open 调用一次会导致它被调用 3 次
【发布时间】:2010-02-03 21:26:16
【问题描述】:

您可以在下面看到我只打电话给File.open 一次,但 rspec 告诉我它收到了 3 次。

def self.import_file(filename)
  current_file = filename.split('/').last
  destroy_all(["filename = ?",current_file])

  unpack_format = "A#{INPUT_FILE_FORMAT.map{|element| element[1]}.join("A")}"
  debugger
  File.open(filename, 'r').each do |line|
    hash_created = create_hash(line, unpack_format).merge({:filename=>current_file})
    create(hash_created)
  end
end  

it "should delete previous records with the same filename" do
  Payrec.should_receive(:destroy_all).with(["filename = ?", "testfile.txt"])
  File.should_receive(:open).and_return([@file_line])
  Payrec.import_file "testfile.txt"
end

输出是

<File (class)> expected :open with (any args) once, but received it 3 times

【问题讨论】:

  • 添加第二个对 import_file 的调用是否会将调用次数变为 4 或 6?如果它是 4,那么无论您执行什么操作,都可能会对其进行 3 次调用,并且您可能需要更深入地挖掘才能找到它们。如果它是 6,那么你调用它的次数是你认为的 3 倍。

标签: ruby-on-rails ruby file rspec


【解决方案1】:

每个人和他的狗都打电话给File.open。我可以想象它调用的很多原因:RSpec 读取它的配置文件,Rails 读取它的配置文件,Cucumber 读取它的配置文件,调试器创建一个临时文件,其他东西创建一个临时文件等等。

您应该检查在调用File.open调用发生的位置什么参数是什么以及为什么 em> 正在发生。

但是,在对核心方法设定期望时,这是您必须处理的事情。

例如,想象一下,您在 Rubinius 上运行您的规范。在 Rubinius 中,编译器是用 Ruby 编写的。它目前不缓存它的编译结果,但当然可以想象它可以缓存它们,然后它自然会使用File.open。砰!现在,您的规范会根据您是否达到 JIT 阈值而随机中断。

或者,更糟糕的是:所有 Rubinius 都广泛使用数组和符号来实现几乎所有内容。尝试对那些设置一些期望!

【讨论】:

  • 这个测试问题的一个解决方案是将File.open调用提取到您自己代码中的一个单独方法中,并简单地断言该方法被调用。
【解决方案2】:

它远非完美,但作为快速了解这些 File.open 调用实际在做什么的方法,请在主脚本的顶部添加猴子补丁:

class File
  class << self
   alias_method :old_open, :open
    def open(*args, &block)
      p args
      block ? block.call(old_open(*args)) : old_open(*args)
    end
  end
end

每当调用 File.open 时,参数都会显示在屏幕上。

【讨论】:

    猜你喜欢
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 2022-05-18
    • 2018-08-27
    • 2020-08-16
    • 2019-06-09
    • 2016-04-12
    • 2011-12-31
    相关资源
    最近更新 更多