问题
I am trying to mock file read with the help of StringIO in Ruby. The following is my test and next to that is my method in the main class.
def test_get_symbols_from_StringIO_file
s = StringIO.new("YHOO,141414")
assert_equal(["YHOO,141414"], s.readlines)
end
def get_symbols_from_file (file_name)
IO.readlines(file_name, ',')
end
I want to know if this is the way we mock the file read and also I would like to know if there is some other method to mock the method in the class rather than doing assert equal with contents.
回答1:
Your method get_symbols_from_file
is never called in the test. You're just testing that StringIO#readlines
works, i.e.:
StringIO.new("YHOO,141414").readlines == ["YHOO,141414"] #=> true
If you want to use a StringIO
instance as a placeholder for your file, you have to change your method to take a File instance rather than a file name:
def get_symbols_from_file(file)
file.readlines(',')
end
Both, File
and StringIO
instances respond to readlines
, so the above implementation can handle both:
def test_get_symbols_from_file
s = StringIO.new("YHOO,141414")
assert_equal(["YHOO,141414"], get_symbols_from_file(s))
end
This test however fails: readlines
includes the line separator, so it returns an array with two elements "YHOO,"
(note the comma) and "141414"
. You are expecting an array with one element "YHOO,141414"
.
Maybe you're looking for something like this:
def test_get_symbols_from_file
s = StringIO.new("YHOO,141414")
assert_equal(["YHOO", "141414"], get_symbols_from_file(s))
end
def get_symbols_from_file(file)
file.read.split(',')
end
If you really want to use IO::readlines
you could create a Tempfile:
require 'tempfile'
def test_get_symbols_from_file
Tempfile.open("foo") { |f|
f.write "YHOO,141414"
f.close
assert_equal(["YHOO", "141414"], get_symbols_from_file(f.path))
}
end
来源:https://stackoverflow.com/questions/19110063/ruby-mock-a-file-with-stringio