2011-12-07 58 views
2

我想測試一個使用CSV.foreach讀取csv文件並對其進行一些處理的方法。它看起來像這樣:你如何嘲笑像「每一個」的方法?

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需要的文件路徑作爲輸入,讀取文件並解析逗號分隔值,返回一個數組爲文件中的每一行。每個數組依次傳遞到代碼塊進行處理。

我想使用摩卡來存根foreach方法,所以我可以控制從我的測試process_csv方法的輸入,沒有任何文件I/O mumbo-jumbo。

。因此測試會是這樣的

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 

我需要一種方法來把我test_input陣列到的東西摩卡可以工作。我認爲我必須使用某種過程或lambda,但是我發現過程,塊和lambdas的世界有點像一個靈機一樣。

+1

請注意,您使用的模擬越多,測試與實施結合在一起。您更改csv分析器,突然您的測試停止工作。還要注意:1)'return -1'是C風格,而不是慣用的Ruby(取而代之,返回'nil')。 2)你可以在'def'級別「拯救」。 – tokland

+0

感謝您的評論tokland。我知道,你說得對,嘲笑。也許我應該更加努力尋找替代方案。我也讚賞其他兩個筆記。你可能會說,我對Ruby很新。 –

+0

可以CSV讀取表示CSV文件內容的字符串嗎?這樣你會避免IO。 –

回答

4

使用Mocha::Expectations#multiple_yields

CSV.expects(:foreach).multiple_yields([row_array1], [row_array2], ...) 

檢查this thread明白爲什麼你必須通過另一個數組裏面的行。

+0

是的,這是我需要的。感謝國王 –

+0

我接受這個解決方案時跳了槍。當我嘗試這種方法時,會有一種特殊的情緒。只有第一個數組元素被分配到行。使用splat(即| * row |)允許我獲得整個數組,但是splat不適用於真正的foreach方法。 –

+2

@Mike E.鑑於行是數組,這是一個特例。試試:multiple_yield([row1],[row2]) – tokland

0

使用Proc對象作爲返回值:

Proc.new{ rand(100) } 
+1

你嘗試過嗎?它不適用於我(它只是返回proc對象)。 – tokland