Rspec загадочно проходит при тестировании вывода XML или CSV - PullRequest
0 голосов
/ 05 сентября 2018

В моем приложении Rails 5 у меня есть это:

class InvoicesController < ApplicationController

  def index
    @invoices = current_account.invoices
    respond_to do |format|
      format.csv do
        invoices_file(:csv)
      end
      format.xml do
        invoices_file(:xml)
      end
    end
  end

private

  def invoices_file(type)
    headers['Content-Disposition'] = "inline; filename=\"invoices.#{type.to_s}\""
  end

end

describe InvoicesController, :type => :controller do

  it "renders a csv attachment" do
    get :index, :params => {:format => :csv}
    expect(response.headers["Content-Type"]).to eq("text/csv; charset=utf-8")
    expect(response).to have_http_status(200)
    expect(response).to render_template :index
  end

end

Моя проблема в том, что мой Spec всегда передает (!), Даже когда я кладу кучу дерьма в мой файл index.csv.erb. Похоже, что файл представления даже не был оценен / протестирован RSpec.

Как это возможно? Что мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 05 сентября 2018

Тесты / спецификации контроллеров - это эти странные, заглушенные создания, рожденные идеей изолированного тестирования контроллеров. Эта идея оказалась довольно ошибочной и в последнее время действительно вышла из моды.

Спецификации контроллера на самом деле не делают реального HTTP-запроса вашему приложению, которое проходит через маршруты. Скорее, они просто имитируют это и пропускают фальшивый запрос.

Для ускорения тестов они также не отображают представления. Вот почему это не ошибка, как вы ожидали. И ответ на самом деле не является реальным объектом ответа стойки.

Вы можете заставить RSpec визуализировать представления с помощью render_views.

describe InvoicesController, :type => :controller do
  render_views
  it "renders a csv attachment" do
    get :index, format: :csv
    expect(response.headers["Content-Type"]).to eq("text/csv; charset=utf-8")
    expect(response).to have_http_status(200)
    expect(response).to render_template :index
  end
end

Но лучшим и более перспективным вариантом является использование спецификации запроса .

Официальная рекомендация команды Rails и основной команды RSpec вместо этого написать спецификации запроса. Спросите спецификации позволяют вам сосредоточиться на одно действие контроллера, но в отличие от тестов контроллера задействовать маршрутизатор, стек промежуточного программного обеспечения, а также запросы и ответы стойки. Это добавляет реализма к тесту, который вы пишете, и помогает избежать многие из проблем, которые являются общими в спецификациях контроллера. http://rspec.info/blog/2016/07/rspec-3-5-has-been-released/

# spec/requests/invoices
require 'rails_helper'
require 'csv'
RSpec.describe "Invoices", type: :request do
  let(:csv) { response.body.parse_csv }
  # Group by the route
  describe "GET /invoices" do
    it "renders a csv attachment" do
      get invoices_path, format: :csv
      expect(response.headers["Content-Type"]).to eq("text/csv; charset=utf-8")
      expect(response).to have_http_status(200)
      expect(csv).to eq ["foo", "bar"] # just an example
    end
  end
end
0 голосов
/ 05 сентября 2018
  1. Параметр формата должен быть указан вне параметров, т. Е. get :index, params: {}, format: :csv}.

  2. Относительно оценочных представлений RSpec, нет, в тестах контроллера это не так, независимо от формата. Тем не менее, можно проверить виды с RSpec: https://relishapp.com/rspec/rspec-rails/v/2-0/docs/view-specs/view-spec

...