Upload pliku - jak to testowac?

Mam taki prosty upload pliku CSV.

W modelu:

def import_links(file) CSV.foreach(file.path) do |row| links.create(Hash[%w(url text description).zip row]) end end
Formularz:

<%= form_tag import_links_board_path(@board), multipart: true do %> <%= file_field_tag :file %><br/> <%= submit_tag "Import" %> <% end %>
Kontroler:

def import_links @board = Board.find(params[:id]) @board.import_links(params[:file]) redirect_to @board end
Powiedzmy, że robie testy dla metody #import_links w modelu.
Pewnie dla większości case’ów chciałbym coś w stylu

before :each do @file = ... end
No i właśnie nie wiem, jak taki ‘file’ wygenerować, czy to ręcznie, czy jeszcze lepiej w FactoryGirl. Będę wdzięczny za pomoc.

  1. File.open i wstaw przykładowy plik do spec/fixtures :slight_smile:
  2. Zestubuj load i dodaj gotowa tablicę z tablicami (? - o ile pamiętam tak CSV zwraca wyniki, na co wskazuje zresztą #zip u Ciebie) wyników wczytania CSV.
CSV.stub(:foreach).and_yield(%w(url1 text1 desc1)).and_yield(%w(url2 text2 desc2))

Powyższy kod zwróci Ci w tym wypadku dwa razy blok - tak, jakbyś miał dwa wiersze w CSV. Więcej do testów raczej nie trzeba. :wink:

Zrobiłem to tak:

before :each do @file = fixture_file_upload '/links.txt', 'text/plain' @board = FactoryGirl.create(:board) end
Musiałem tylko wrzucić przykładowy plik do spec/fixtures i dodać ‘include ActionDispatch::TestProcess’ w ‘spec_helper.rb’. Wygląda, że działa.

Przetestowałem twoją opcję 1 i też działa, więc nie wiem co teraz lepiej zostawić.
Co do ‘stubowania loada’ to na razie nie wiem co to stub, ale często się pojawia, więc chyba będę musiał zgłębić temat :slight_smile:

Stub zastępuje w skrócie metody obiektu / klasy, na której wykonujesz ową metodę (oczywiście tylko ja czas danego testu / grupy testów (w przypadku before)!). Czyli, jeśli masz obiekt, albo klasę z metodą load i zrobisz obiekt.stub(:load) / klasa.stub(:load), to zwrot stubowanej metody ma “pierszeństwo”, przed właściwą implementacją. Przykład:

class A def add(a,b) a+b end end A.add(2,2) # => 4 A.stub(:add).with(2,2).and_return(3) A.add(2,2) # => 3
Dzięki temu unikasz w testach np. skomplikowanych i długich obliczeń / połączeń z serwerami, których tak na prawdę nue potrzebujesz testować w danym teście - zauważ, że nie chcesz testować ładowania u siebie pliku CSV, a interesuje Cię jedynie, jak wykona się metoda ze zwróconą wartością przez CSV.foreach.

Oczywiście stubuj z głową, inaczej nie przetestujesz niczego. :wink: W tym wypadku raczej jest to uzasadnione, jeśli nie chcesz wczytywać pliku.

Dzięki wielkie za wytłumaczenie, na pewno się przyda.