2009-07-24 60 views
91

我有一個控制器負責接受JSON文件,然後處理JSON文件來爲我們的應用程序做一些用戶維護。在用戶測試文件上傳和處理工作時,當然我想在我們的測試中自動執行測試用戶維護的過程。我如何在功能測試框架中將文件上傳到控制器?如何在rails中測試文件上傳?

回答

99

爲這個問題搜索並找不到它,或者它的堆棧溢出的答案,但在其他地方找到它,所以我要求在SO上提供它。

Rails框架有一個函數fixture_file_upload(Rails 2Rails 3Rails 5),它會搜索你的燈具目錄中指定的文件,並使其可用於功能測試控制器測試文件。要使用它:

1)將您的文件上傳到您的fixtures/files子目錄中的測試中進行測試。

2)在你的單元測試中,你可以通過調用fixture_file_upload('path','mime-type')來獲得你的測試文件。

例如爲:

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

3)調用POST方法來打你想要的控制器動作,路過fixture_file_upload作爲上傳參數返回的對象。

如:

post :bookmark, :bulkfile => bulk_json

或者Rails中5:post :bookmark, params: {bulkfile: bulk_json}

這將通過模擬的後處理使用文件的將它視爲拷貝到您的燈具目錄下運行,然後返回到你單位測試,以便您可以開始檢查帖子的結果。

+2

這不適用於rails 3. action_controller/test_process文件在activesupport 3中似乎不可用。我在這裏打開了一個新的問題 - http://stackoverflow.com/questions/3966263/attachment-fu-testing-in-rails-3 – Chirantan 2010-10-19 08:33:35

+0

答案中的鏈接是404,還是隻爲我? – Ernest 2010-12-14 11:46:06

+0

豎起大拇指&非常感謝! – 2011-03-16 09:51:01

4

您想使用fixtures_file_upload。您將把測試文件放在fixtures目錄的子目錄中,然後將路徑傳遞給fixtures_file_upload。下面是一個example of code,使用夾具文件上載

9

從Rspec的圖書,B13.0:

Rails的提供的ActionController :: TestUploadedFile可用於類來表示在一個params哈希表上傳的文件控制器規格如下:

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 

該規範將要求您在spec/fixtures目錄中有一個test_avatar.png圖像。這將需要該文件,將其上傳到控制器,並且控制器將創建並保存真實的用戶模型。

0

如果你正在你的控制器文件具有以下

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

然後嘗試在你的規格如下:

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 

這將使假法「臨時文件」的方法,這將返回加載文件的路徑。

76

Mori的回答是正確的,除了在Rails 3中,而不是「ActionController :: TestUploadedFile.new」,你必須使用「Rack :: Test :: UploadedFile.new」。

然後,可以將創建的文件對象用作Rspec或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 
22

我覺得這是更好地使用新ActionDispatch :: HTTP :: UploadedFile的這種方式:

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

這樣,您就可以使用您使用您的驗證相同的方法(例如臨時文件)。

1

如果您使用工廠女孩使用默認導軌測試。下面的代碼很好。

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

注意:您將不得不在/test/images/100_100.jpg保留一個虛擬形象。

它完美的作品。

乾杯!