简体   繁体   English

如何在rails中测试文件上传?

[英]How do I test a file upload in rails?

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. 我有一个控制器,负责接受JSON文件,然后处理JSON文件,为我们的应用程序做一些用户维护。 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? 如何在功能测试框架中将文件上传到控制器?

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 2 Rails 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. rails框架有一个函数fixture_file_uploadRails 2 Rails 3Rails 5 ),它将在您的fixtures目录中搜索指定的文件,并使其在功能测试中作为控制器的测试文件。 To use it: 要使用它:

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')来获取测试文件。

eg: 例如:

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返回的对象作为上传的参数。

eg: 例如:

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. 这将使用fixtures目录中文件的Tempfile副本运行模拟后期处理,然后返回到单元测试,以便您可以开始检查帖子的结果。

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

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). 这样,您可以使用在验证中使用的相同方法(例如tempfile)。

From The Rspec Book, B13.0: 来自The Rspec Book,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. 此规范要求您在spec / fixtures目录中有一个test_avatar.png图像。 It would take that file, upload it to the controller, and the controller would create and save a real User model. 它需要该文件,将其上传到控制器,控制器将创建并保存真实的用户模型。

You want to use fixtures_file_upload . 你想使用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. 您将测试文件放在fixtures目录的子目录中,然后将路径传递给fixtures_file_upload。 Here is an example of code , using fixture file upload 以下是使用fixture文件上传的代码示例

If you are using default rails test with factory girl. 如果您正在使用工厂女孩的默认轨道测试。 Fine below code. 在代码下面很好。

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! 干杯!

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'方法,该方法将返回加载文件的路径。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM