Ruby-on-rails 如何在 Rails 中测试文件上传?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1178587/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I test a file upload in rails?
提问by animal
I have a controller which is responsible for accepting JSON files and then processing the JSON files to do some user maintenance for our application. In user testing the file upload and processing works, but of course I would like to automate the process of testing the user maintenance in our testing. How can I upload a file to a controller in the functional testing framework?
我有一个控制器,它负责接受 JSON 文件,然后处理 JSON 文件以对我们的应用程序进行一些用户维护。在用户测试中文件上传和处理工作,但我当然希望在我们的测试中自动化测试用户维护的过程。如何将文件上传到功能测试框架中的控制器?
回答by animal
Searched for this question and could not find it, or its answer on Stack Overflow, but found it elsewhere, so I'm asking to make it available on SO.
搜索了这个问题但找不到它,或者它在 Stack Overflow 上的答案,但在其他地方找到了,所以我要求在 SO 上提供它。
The rails framework has a function fixture_file_upload(Rails 2Rails 3, Rails 5), which will search your fixtures directory for the file specified and will make it available as a test file for the controller in functional testing. To use it:
rails 框架有一个函数fixture_file_upload(Rails 2 Rails 3,Rails 5),它将在您的设备目录中搜索指定的文件,并将其作为控制器在功能测试中的测试文件。要使用它:
1) Put your file to be uploaded in the test in your fixtures/files subdirectory for testing.
1) 将您要上传的文件放在您的 fixtures/files 子目录中进行测试。
2) In your unit test you can get your testing file by calling fixture_file_upload('path','mime-type').
2) 在您的单元测试中,您可以通过调用 fixture_file_upload('path','mime-type') 来获取您的测试文件。
e.g.:
例如:
bulk_json = fixture_file_upload('files/bulk_bookmark.json','application/json')
bulk_json = fixture_file_upload('files/bulk_bookmark.json','application/json')
3) call the post method to hit the controller action you want, passing the object returned by fixture_file_upload as the parameter for the upload.
3)调用post方法命中你想要的控制器动作,将fixture_file_upload返回的对象作为上传的参数传递。
e.g.:
例如:
post :bookmark, :bulkfile => bulk_json
post :bookmark, :bulkfile => bulk_json
Or in Rails 5: post :bookmark, params: {bulkfile: bulk_json}
或者在 Rails 5 中: post :bookmark, params: {bulkfile: bulk_json}
This will run through the simulated post process using a Tempfile copy of the file in your fixtures directory and then return to your unit test so you can start examining the results of the post.
这将使用夹具目录中文件的 Tempfile 副本运行模拟后处理,然后返回到单元测试,以便您可以开始检查后处理结果。
回答by Victor Grey
Mori's answer is correct, except that in Rails 3 instead of "ActionController::TestUploadedFile.new" you have to use "Rack::Test::UploadedFile.new".
Mori 的回答是正确的,除了在 Rails 3 中而不是“ActionController::TestUploadedFile.new”你必须使用“Rack::Test::UploadedFile.new”。
The file object that is created can then be used as a parameter value in Rspec or TestUnit tests.
创建的文件对象然后可以用作 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
回答by David Morales
I think it's better to use the new ActionDispatch::Http::UploadedFile this way:
我认为这样使用新的 ActionDispatch::Http::UploadedFile 会更好:
uploaded_file = ActionDispatch::Http::UploadedFile.new({
:tempfile => File.new(Rails.root.join("test/fixtures/files/test.jpg"))
})
assert model.valid?
This way you can use the same methods you are using in your validations (as for example tempfile).
这样您就可以使用您在验证中使用的相同方法(例如临时文件)。
回答by Mori
From The Rspec Book, B13.0:
来自 Rspec 书,B13.0:
Rails' provides an ActionController::TestUploadedFile class which can be used to represent an uploaded file in the params hash of a controller spec, like this:
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
This spec would require that you have a test_avatar.png image in the spec/fixtures directory. It would take that file, upload it to the controller, and the controller would create and save a real User model.
该规范要求您在 spec/fixtures 目录中有一个 test_avatar.png 图像。它将获取该文件,将其上传到控制器,控制器将创建并保存一个真正的用户模型。
回答by Rob Di Marco
You want to use fixtures_file_upload. You will put your test file in a subdirectory of the fixtures directory and then pass in the path to fixtures_file_upload. Here is an example of code, using fixture file upload
您想使用fixtures_file_upload。您将测试文件放在 fixtures 目录的子目录中,然后传递到 fixtures_file_upload 的路径。这是一个代码示例,使用夹具文件上传
回答by Manish Shrivastava
If you are using default rails test with factory girl. Fine below code.
如果您使用工厂女孩的默认 rails 测试。下面的代码很好。
factory :image_100_100 do
image File.new(File.join(::Rails.root.to_s, "/test/images", "100_100.jpg"))
end
Note: you will have to keep an dummy image in /test/images/100_100.jpg.
注意:您必须在/test/images/100_100.jpg.
It works perfectly.
它完美地工作。
Cheers!
干杯!
回答by Esenbek Kydyr uulu
if you are getting the file in your controller with the following
如果您使用以下命令在控制器中获取文件
json_file = params[:json_file]
FileUtils.mv(json_file.tempfile, File.expand_path('.')+'/tmp/newfile.json')
then try the following in your specs:
然后在您的规格中尝试以下操作:
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
This will make the fake method to 'tempfile' method, which will return the path to the loaded file.
这将使假方法变为 'tempfile' 方法,该方法将返回加载文件的路径。

