What's the best way to test the following code using RSpec? And what should I be testing for? The show action opens a file and streams it. Also, if the action relies on a file existing somewhere, can I test that?
def show
image_option = params[:image_option]
respond_to do |format|
format.js
format.pdf {open_bmap_file("#{@bmap.bmap_pdf_file}", 'application/pdf', "#{@bmap.bmap_name}.pdf", "pdf", "pdf")}
format.png {open_bmap_file("#{@bmap.bmap_png_file}", 'image/png', "#{@bmap.bmap_name}.png", "png", image_option)}
end
end
private
def open_bmap_file(filename, application_type, send_filename, format, image_option = nil)
filename = "app/assets/images/image_not_available_small.png" unless File.exist? filename
path = Bmap.bmaps_pngs_path
case image_option
when "image"
filename = "#{@bmap.bmap_name}.png"
when "large_thumbnail"
filename = "#{@bmap.bmap_name}_large_thumb.png"
when "thumbnail"
filename = "#{@bmap.bmap_name}_thumb.png"
when "pdf"
filename = "#{@bmap.bmap_name}.pdf"
path = Bmap.bmaps_pdfs_path
else
filename = "#{@bmap.bmap_name}.pdf"
path = Bmap.bmaps_pdfs_path
end
begin
File.open(path + filename, 'rb') do |f|
send_data f.read, :disposition => image_option == "pdf" ? 'attachment' : 'inline', :type => application_type, :filename => send_filename
end
rescue
flash[:error] = 'File not found.'
redirect_to root_url
end
RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications. Even though it has a very rich and powerful DSL (domain-specific language), at its core it is a simple tool which you can start using rather quickly.
RSpec is a unit test framework for the Ruby programming language. RSpec is different than traditional xUnit frameworks like JUnit because RSpec is a Behavior driven development tool. What this means is that, tests written in RSpec focus on the "behavior" of an application being tested.
The word it is another RSpec keyword which is used to define an “Example”. An example is basically a test or a test case. Again, like describe and context, it accepts both class name and string arguments and should be used with a block argument, designated with do/end.
I needed to test send_data
in a controller action that downloads a csv file, and I did it in the following way.
def index
respond_to do |format|
format.csv do
send_data(Model.generate_csv,
type: 'text/csv; charset=utf-8; header=present',
filename: "report.csv",
disposition: 'attachment')
end
end
end
context "when format is csv" do
let(:csv_string) { Model.generate_csv }
let(:csv_options) { {filename: "report.csv", disposition: 'attachment', type: 'text/csv; charset=utf-8; header=present'} }
it "should return a csv attachment" do
@controller.should_receive(:send_data).with(csv_string, csv_options).
and_return { @controller.render nothing: true } # to prevent a 'missing template' error
get :index, format: :csv
end
end
context "when format is csv" do
let(:csv_string) { Model.generate_csv }
let(:csv_options) { {filename: "report.csv", disposition: 'attachment', type: 'text/csv; charset=utf-8; header=present'} }
it "should return a csv attachment" do
expect(@controller).to receive(:send_data).with(csv_string, csv_options) {
@controller.render nothing: true # to prevent a 'missing template' error
}
get :index, format: :csv
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With