How to test file upload with Grape Framework
Thu, Jan 28, 2016Grape is a Rack based Ruby framework for building API. It’s only a few years old and has not reached version 1.0 yet. The main github page has a very good documentation but is still not as complete as Rails guide. In this post, I will discuss how to test file upload endpoint with RSpec.
Suppose you have an endpoint that takes a file input.
class MyAPI::FileUpload < Grape::API
desc 'Upload a file'
params do
require :file, type: File
end
post '/upload' do
# params[:file][:tempfile] is a Tempfile
size = File.size(params[:file][:tempfile])
present {
filename: params[:file][:filename],
type: params[:file][:type],
size: size
}
end
end
How do we actually send a real file to the endpoint in your RSpec test?
In Rails we have a fixture_file_upload
helper.
post :upload, file: fixture_file_upload('images/image.jpg', 'image/jpg')
# Under the hood, fixture_file_upload basically creates
Rack::Test::UploadedFile.new(File.open(File.join(Rails.root, '/spec/fixtures/images/image.jpg')), 'image/jpg')
Because Grape is just a Rack based framework, you can use the same way to test file upload.
That is by creating an instance of Rack::Test::UploadedFile
.
RSpec.describe MyAPI::FileUpload do
it 'upload a file' do
file_path = '/path/to/image.jpg'
post '/upload', file: Rack::Test::UploadedFile.new(file_path, 'image/jpeg')
json_response = JSON.parse(last_response.body)
expect(json_response[:filename]).to eq('image.jpg')
expect(json_response[:type]).to eq('image/jpeg')
expect(json_response[:size]).to eq(File.size(file_path))
end
end