Тестовая загрузка pdf с помощью rspec и pdfkit

Я разрабатываю приложение rails 3.2, с помощью которого пользователи могут загружать файлы в формате PDF. Мне очень нравится разработка, основанная на тестировании, с использованием сопоставителей rspec и shoulda, но я не понимаю, с этим.

В моем контроллере есть следующий код:

def show_as_pdf
  @client = Client.find(params[:client_id])
  @invoice = @client.invoices.find(params[:id])

  PDFKit.configure do |config|
    config.default_options = {
      :footer_font_size => "6",
      :encoding => "UTF-8",
      :margin_top=>"1in",
      :margin_right=>"1in",
      :margin_bottom=>"1in",
      :margin_left=>"1in"
    }
  end

  pdf = PDFKit.new(render_to_string "invoices/pdf", layout: false)
  invoice_stylesheet_path = File.expand_path(File.dirname(__FILE__) + "/../assets/stylesheets/pdfs/invoices.css.scss")
  bootstrap_path = File.expand_path(File.dirname(__FILE__) + "../../../vendor/assets/stylesheets/bootstrap.min.css")

  pdf.stylesheets << invoice_stylesheet_path
  pdf.stylesheets << bootstrap_path
  send_data pdf.to_pdf, filename: "#{@invoice.created_at.strftime("%Y-%m-%d")}_#{@client.name.gsub(" ", "_")}_#{@client.company.gsub(" ", "_")}_#{@invoice.number.gsub(" ", "_")}", type: "application/pdf"
  return true
end

Это довольно простой код, все, что он делает, - это настраивает мой PDFKit и загружает сгенерированный PDF-файл. Теперь я хочу протестировать все это, в том числе:

  • Назначение переменных экземпляра (легко, конечно, и это работает)
  • Отправка данных, то есть рендеринг pdf => И здесь я застрял

Я пробовал следующее:

controller.should_receive(:send_data)

но это дает мне

Failure/Error: controller.should_receive(:send_data)
   (#<InvoicesController:0x007fd96fa3e580>).send_data(any args)
       expected: 1 time
       received: 0 times

Кто-нибудь знает способ проверить, действительно ли pdf загружается / отправляется? Кроме того, что еще вы видите, что следует протестировать на предмет хорошего тестового покрытия? Например, было бы неплохо протестировать тип данных, то есть application / pdf.

Спасибо!


person weltschmerz    schedule 07.03.2013    source источник


Ответы (2)


Не уверен, почему вы получаете этот сбой, но вы можете вместо этого проверить заголовки ответов:

response_headers["Content-Type"].should == "application/pdf"
response_headers["Content-Disposition"].should == "attachment; filename=\"<invoice_name>.pdf\""

Вы просили совета по поводу лучшего покрытия тестами. Я подумал, что порекомендую это: https://www.destroyallsoftware.com/screencasts. Эти скринкасты оказали огромное влияние на мое понимание разработки через тестирование - настоятельно рекомендую!

person Jonathan MacDonald    schedule 07.03.2013
comment
Спасибо, но, к сожалению, это дает мне undefined method 'response_headers' - что я делаю не так? - person weltschmerz; 08.03.2013
comment
Ха-ха, забыл get :show_as_pdf :) Это решает все проблемы. Большое спасибо! - person weltschmerz; 08.03.2013
comment
Я хотел бы протестировать содержимое загрузки, но с селеном, который, похоже, не работает, кто-нибудь знает об этом больше? - person Ian Vaughan; 11.01.2015
comment
использование response.headers["Content-Type"] работает для меня - person xhh; 04.06.2015
comment
У меня это работает с рельсами 4 / rspec 3.5.0, но не с рельсами 5. Есть идеи? - person ChaosPredictor; 23.09.2016

Я рекомендую использовать гем pdf-Inspector для написания спецификаций для действий Rails, связанных с PDF.

Вот примерная спецификация (которая предполагает, что действие Rails #report записывает данные о Ticket модели в сгенерированный PDF-файл):

describe 'GET /report.pdf' do
  it 'returns downloadable PDF with the ticket' do
    ticket = FactoryGirl.create :ticket

    get report_path, format: :pdf

    expect(response).to be_successful

    analysis = PDF::Inspector::Text.analyze response.body

    expect(analysis.strings).to include ticket.state
    expect(analysis.strings).to include ticket.title
  end
end
person Paweł Gościcki    schedule 05.11.2016
comment
Примечание: эта спецификация должна быть спецификацией запроса, а не спецификации контроллера, последняя заглушает render пустую строку. - person phil pirozhkov; 30.12.2016