2009-07-24 7 views
91

Mam kontroler, który jest odpowiedzialny za akceptowanie plików JSON, a następnie przetwarzanie plików JSON, aby wykonać pewne czynności konserwacyjne dla użytkownika dla naszej aplikacji. W testowaniu użytkownika przesyłanie i przetwarzanie plików działa, ale oczywiście chciałbym zautomatyzować proces testowania konserwacji przez użytkownika w naszych testach. Jak mogę przesłać plik do kontrolera w strukturze testów funkcjonalnych?Jak przetestować przesyłanie plików w szynach?

Odpowiedz

99

Szukałem tego pytania i nie mogłem go znaleźć lub jego odpowiedzi na Stack Overflow, ale znalazłem je gdzie indziej, więc proszę o udostępnienie go na SO.

Ramy szyny ma fixture_file_upload funkcyjny (Rails 2Rails 3, Rails 5), który wyszuka katalog Oprawy do pliku określonego i udostępni je w postaci pliku testowego dla testów funkcjonalnych w kontrolerze. Aby go użyć:

1) Umieść plik do przesłania w teście do podkatalogu urządzenia/pliki do testów.

2) W teście jednostki można uzyskać plik testowy, wywołując fixture_file_upload ("ścieżka", "typ mime").

np .:

bulk_json = fixture_file_upload('files/bulk_bookmark.json','application/json')

3) wywołanie metody POST trafić działanie kontrolera chcesz, przekazując obiekt zwrócony przez fixture_file_upload jako parametr dla upload.

np

post :bookmark, :bulkfile => bulk_json

albo w Rails 5: post :bookmark, params: {bulkfile: bulk_json}

Spowoduje to uruchomienie przez symulowanego procesu po użyciu tempfile kopię pliku w katalogu lamp, a następnie powrócić do swojej jednostki przetestuj, aby rozpocząć badanie wyników postu.

+2

To nie działa na szynach 3. Plik action_controller/test_process nie jest dostępny w activesupport 3 wydaje się. Otworzyłem nowe pytanie o to samo tutaj - http://stackoverflow.com/questions/3966263/attachment-fu-testing-in-rails-3 – Chirantan

+0

Link w Twojej odpowiedzi to 404, czy jest to tylko dla mnie? – Ernest

+0

Kciuki w górę i dziękuję bardzo! –

4

Chcesz użyć fixtures_file_upload. Umieszczasz swój plik testowy w podkatalogu katalogu urządzeń, a następnie przekazujesz ścieżkę do fixtures_file_upload. Oto example of code, wykorzystując plik Oprawa przesłać

9

Z rspec Book, B13.0:

Rails' stanowi ActionController :: TestUploadedFile klasy, które mogą być wykorzystane do reprezentowania plik przesłany w hash params Urządzony specyfikacja kontrolera, na przykład:

describe UsersController, "POST create" do 
    after do 
    # if files are stored on the file system 
    # be sure to clean them up 
    end 

    it "should be able to upload a user's avatar image" do 
    image = fixture_path + "/test_avatar.png" 
    file = ActionController::TestUploadedFile.new image, "image/png" 
    post :create, :user => { :avatar => file } 
    User.last.avatar.original_filename.should == "test_avatar.png" 
    end 
end 

Ta specyfikacja wymagać będzie posiadania obrazu test_avatar.png w katalogu spec/fixtures. Pobrałby ten plik, przesłał go do kontrolera, , a kontroler utworzyłby i zapisze prawdziwy model użytkownika.

+1

Otrzymuję komunikat "niezainicjowany stały ActionController :: TestUploadedFile" po uruchomieniu testu z tym kodem. Coś innego, czego bym potrzebował w pliku? –

+0

Wydaje się być przestarzałe już w Railsach 2.3. W przypadku Rails 3.0 i nowszych [tutaj: jak to zrobić] (http://apidock.com/rails/ActionDispatch/TestProcess/fixture_file_upload) używając urządzeń – Sebastialonso

0

jeśli otrzymujesz plik w kontrolerze z następującym

json_file = params[:json_file] 
FileUtils.mv(json_file.tempfile, File.expand_path('.')+'/tmp/newfile.json') 

następnie spróbuj wykonać następujące czynności w swoich specyfikacji:

json_file = mock('JsonFile') 
json_file.should_receive(:tempfile).and_return("files/bulk_bookmark.json") 
post 'import', :json_file => json_file 
response.should be_success 

To uczyni fałszywy sposób na „tempfile” metoda, która zwróci ścieżkę do załadowanego pliku.

76

Odpowiedź Mori jest poprawna, z tym że w Railsach 3 zamiast "ActionController :: TestUploadedFile.new" musisz użyć "Rack :: Test :: UploadedFile.new".

Utworzony obiekt pliku może być następnie użyty jako wartość parametru w testach Rspec lub TestUnit.

test "image upload" do 
    test_image = path-to-fixtures-image + "/Test.jpg" 
    file = Rack::Test::UploadedFile.new(test_image, "image/jpeg") 
    post "/create", :user => { :avatar => file } 
    # assert desired results 
    post "/create", :user => { :avatar => file }  

    assert_response 201 
    assert_response :success 
end 
+0

Ta metoda jest dobrą alternatywą, gdy twoje urządzenia nie znajdują się w/test/fixtures. Jeśli na przykład generujesz dynamicznie niektóre pliki do testów, mogą one znajdować się w folderze/tmp. –

+2

Działa to bezbłędnie z Rails 4 również. Dzięki! – Waseem

22

myślę, że lepiej jest użyć nowego ActionDispatch :: Http :: UploadedFile ten sposób:

uploaded_file = ActionDispatch::Http::UploadedFile.new({ 
    :tempfile => File.new(Rails.root.join("test/fixtures/files/test.jpg")) 
}) 
assert model.valid? 

W ten sposób można korzystać z tych samych metod używasz w swoim walidacji (jak na przykład tempfile).

1

Jeśli używasz domyślnego testu szyn z dziewczyną z fabryki. Dokładnie poniżej kodu.

factory :image_100_100 do 
    image File.new(File.join(::Rails.root.to_s, "/test/images", "100_100.jpg")) 
end 

Uwaga: będziesz musiał zachować fikcyjny obraz w /test/images/100_100.jpg.

Działa doskonale.

Pozdrawiam!