Question

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.

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top