我如何testing一个file upload在铁轨?

我有一个控制器负责接受JSON文件,然后处理JSON文件来为我们的应用程序做一些用户维护。 在用户testingfile upload和处理工作中,当然我想在testing中自动完成用户维护的testing过程。 如何在functiontesting框架中将file upload到控制器?

search这个问题,找不到它,或者它的堆栈溢出的答案,但在其他地方find它,所以我要求在SO上提供它。

rails框架有一个函数fixture_file_upload( Rails 2 Rails 3 ),它将search你指定的文件夹具目录,并在functiontesting中将它作为控制器的testing文件使用。 要使用它:

1)把你的file upload到你的fixtures / files子目录中进行testing。

2)在你的unit testing中,你可以通过调用fixture_file_upload('path','mime-type')来获得你的testing文件。

例如:

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

3)调用post方法命中你想要的控制器动作,传递fixture_file_upload返回的对象作为上传的参数。

例如:

post :bookmark, :bulkfile => bulk_json

这将通过在你的fixtures目录中使用Tempfile文件的副本运行,然后返回到你的unit testing,所以你可以开始检查文章的结果。

Mori的答案是正确的,除了在Rails 3而不是“ActionController :: TestUploadedFile.new”你必须使用“Rack :: Test :: UploadedFile.new”。

然后,可以将创build的文件对象用作Rspec或TestUnittesting中的参数值。

 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 

我认为这样最好使用新的ActionDispatch :: Http :: UploadedFile:

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

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

从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图片。 这将需要该文件,将其上传到控制器,控制器将创build并保存一个真正的用户模型。

你想使用fixtures_file_upload 。 您将把testing文件放在fixtures目录的子目录中,然后将path传递给fixtures_file_upload。 这是一个代码示例 ,使用夹具file upload

如果您使用工厂女孩使用默认的轨道testing。 细下面的代码。

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

注意:你将不得不在/testhttp://img.dovov.com100_100.jpg保留一个虚拟的图像。

它完美的作品。

干杯!

如果您使用以下方式获取控制器中的文件

 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'方法,这将返回到加载文件的path。