使用 rspec-ails 测试文件上传

我想测试一个文件在轨道上传,但不确定如何做到这一点。

下面是控制器代码:

def uploadLicense
#Create the license object
@license = License.create(params[:license])




#Get Session ID
sessid = session[:session_id]


puts "\n\nSession_id:\n#{sessid}\n"


#Generate a random string
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(5) { |i| newpass << chars[rand(chars.size-1)] }


#Get the original file name
upload=params[:upload]
name =  upload['datafile'].original_filename


@license.format = File.extname(name)


#calculate license ID and location
@license.location = './public/licenses/' + sessid + newpass + name


#Save the license file
#Fileupload.save(params[:upload], @license.location)
File.open(@license.location, "wb") { |f| f.write(upload['datafile'].read) }


#Set license ID
@license.license_id = sessid + newpass


#Save the license
@license.save


redirect_to :action => 'show', :id => @license.id
end

我已经试过这个规格,但它不工作:

it "can upload a license and download a license" do
file = File.new(Rails.root + 'app/controllers/lic.xml')
license = HashWithIndifferentAccess.new
license[:datafile] = file
info = {:id => 4}
post :uploadLicense, {:license => info, :upload => license}
end

如何使用 rspec 模拟文件上载?

83145 次浏览

我不确定你是否可以单独使用 RSpec 测试文件上传。你试过 水豚吗?

从请求规范中使用 capybara 的 attach_file方法很容易测试文件上传。

例如(此代码只是一个演示) :

it "can upload a license" do
visit upload_license_path
attach_file "uploadLicense", /path/to/file/to/upload
click_button "Upload License"
end


it "can download an uploaded license" do
visit license_path
click_link "Download Uploaded License"
page.should have_content("Uploaded License")
end

我还没有使用 RSpec 完成这项工作,但是我有一个 Test: : Unit 测试,它对上传照片执行类似的操作。我将上传的文件设置为 ActionDispatch: : Http: : UploadedFile 的一个实例,如下所示:

test "should create photo" do
setup_file_upload
assert_difference('Photo.count') do
post :create, :photo => @photo.attributes
end
assert_redirected_to photo_path(assigns(:photo))
end




def setup_file_upload
test_photo = ActionDispatch::Http::UploadedFile.new({
:filename => 'test_photo_1.jpg',
:type => 'image/jpeg',
:tempfile => File.new("#{Rails.root}/test/fixtures/files/test_photo_1.jpg")
})
@photo = Photo.new(
:title => 'Uploaded photo',
:description => 'Uploaded photo description',
:filename => test_photo,
:public => true)
end

类似的东西可能也适合你。

您可以使用 Fixture _ file _ load方法来测试文件上传: 将测试文件放在 “{ Rails.root }/spec/fixture/files”目录中

before :each do
@file = fixture_file_upload('files/test_lic.xml', 'text/xml')
end


it "can upload a license" do
post :uploadLicense, :upload => @file
response.should be_success
end

如果您期望文件的形式为 Params [“上载”][“数据文件”]

it "can upload a license" do
file = Hash.new
file['datafile'] = @file
post :uploadLicense, :upload => file
response.should be_success
end

如果包含 Rack: : Test * ,只需包含测试方法

describe "my test set" do
include Rack::Test::Methods

然后您可以使用 UploadedFile 方法:

post "/upload/", "file" => Rack::Test::UploadedFile.new("path/to/file.ext", "mime/type")

注意: 我的示例基于 Sinatra,它扩展了 Rack,但是应该使用 Rails,它也使用 Rack,TTBOMK

我不得不添加这两个包括让它工作:

describe "my test set" do
include Rack::Test::Methods
include ActionDispatch::TestProcess

这是我如何与 Rails 6RSpecRack::Test::UploadedFile做到这一点

describe 'POST /create' do
it 'responds with success' do
post :create, params: {
license: {
picture: Rack::Test::UploadedFile.new("#{Rails.root}/spec/fixtures/test-pic.png"),
name: 'test'
}
}


expect(response).to be_successful
end
end

不要包含 ActionDispatch::TestProcess 或任何其他代码,除非你确定你包含了什么。