Why would using File.open call once result in it being called 3 times according to rspec
Below you can see that I'm calling File.open
only once but rspec is telling me it received it 3 times.
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.开发者_如何学Ctxt"])
File.should_receive(:open).and_return([@file_line])
Payrec.import_file "testfile.txt"
end
The output is
<File (class)> expected :open with (any args) once, but received it 3 times
Everybody and his dog calls File.open
. I could imagine a ton of reasons why it would called: RSpec reading its config file, Rails reading its config file(s), Cucumber reading its config file, the debugger creating a temporary file, something else creating a temporary file and so on.
You should check who is calling File.open
, where that call happens, what the arguments are and why that is happening.
But, this is something you will just have to deal with, when setting expectations on core methods.
Imagine, for example, you are running your specs on Rubinius. In Rubinius, the compiler is written in Ruby. It doesn't currently cache its compiled results, but it is certainly conceivable that it could cache them, and then it would naturally use File.open
. Bam! Now your specs randomly break depending on whether you hit the JIT threshold or not.
Or, even worse: all of Rubinius uses arrays and symbols extensively to implement just about everything. Try setting some expectations on those!
It's far from perfect, but as a quick hack for finding out what these File.open calls are actually doing, monkey patch this in at the top of your main script:
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
Whenever File.open is called, the arguments will be put to screen.
精彩评论