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

时间:2009-07-24 15:57:54

标签: ruby-on-rails ruby testing upload

我有一个控制器,负责接受JSON文件,然后处理JSON文件,为我们的应用程序做一些用户维护。在用户测试文件上传和处理工作,但我当然希望在我们的测试中自动化测试用户维护的过程。如何在功能测试框架中将文件上传到控制器?

7 个答案:

答案 0 :(得分:109)

搜索了这个问题并且无法找到它,或者它在Stack Overflow上的答案,但在其他地方找到它,所以我要求在SO上提供它。

rails框架有一个函数fixture_file_uploadRails 2 Rails 3Rails 5),它将在你的fixtures目录中搜索指定的文件,并将其作为一个功能测试中控制器的测试文件。使用它:

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

e.g:

post :bookmark, :bulkfile => bulk_json

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

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

答案 1 :(得分:82)

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

答案 2 :(得分:23)

我认为最好以这种方式使用新的ActionDispatch :: Http :: UploadedFile:

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

这样您就可以使用在验证中使用的相同方法(例如tempfile)。

答案 3 :(得分:8)

来自Rspec Book,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图像。它需要该文件,将其上传到控制器, 并且控制器将创建并保存真实的用户模型。

答案 4 :(得分:4)

您想使用fixtures_file_upload。您将测试文件放在fixtures目录的子目录中,然后将路径传递给fixtures_file_upload。这是example of code,使用夹具文件上传

答案 5 :(得分: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中保留虚拟图像。

效果很好。

干杯!

答案 6 :(得分: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

这将使伪方法成为'tempfile'方法,该方法将返回加载文件的路径。