I'm trying to test a method that uses CSV.foreach to read in a csv file and does some processing on it. It looks something like this:
require 'csv'
class Csv_processor
def self.process_csv(file)
begin
CSV.foreach(file) do { |row|
# do some processing on the row
end
rescue CSV::MalformedCSVError
return -1
end
end
end
CSV.foreach takes a file path as input, reads the file and parses the comma separated values, returning an array for each row in the file. Each array is passed in turn to the code block for processing.
I'd like to use Mocha to stub the foreach
method so I can control the input to the process_csv
method from my test without any file I/O mumbo-jumbo.
So the test would be something like this
test "rejects input with syntax errors" do
test_input = ['"sytax error" 1, 2, 3', '4, 5, 6', '7, 8, 9']
CSV.expects(:foreach).returns( ??? what goes here ??? )
status = Csv_processor.process_csv("dummy")
assert_equal -1, status, "Status does not indicate error: #{status}"
end
I need a way to turn my test_input
array into something Mocha can work with. I think I have to use some sort of proc or lambda, but I find the world of procs, blocks and lambdas a bit of a mind-bender.
Use Mocha::Expectations#multiple_yields:
CSV.expects(:foreach).multiple_yields([row_array1], [row_array2], ...)
Check this thread to see why you have to pass the rows inside another array.