У меня есть контроллер:Как протестировать контроллер без попадания в базу данных?
class InvoicesController < ApplicationController
def edit
@invoice = Invoice.includes(:client, :document_status).find(params[:id])
return head :forbidden unless @invoice.editable?
end
end
Я хочу написать тест, но без удара по базе данных:
describe InvoicesController do
describe '#edit' do
let(:invoice_id) { '1' }
let(:invoice) { double(Invoice, editable?: false) }
let(:invoice_includes) { double }
before do
allow(invoice_includes).to receive(:find).with(invoice_id) { invoice }
allow(Invoice).to receive(:includes).with(:client, :document_status) { invoice_includes }
end
subject { get :edit, params: {id: invoice_id} }
it { is_expected.to have_http_status(403) }
end
end
Есть ли лучший подход? Мне не нравится эта цепочка allow
, но я не могу придумать ничего лучшего. Установка переменной экземпляра @invoice
в тесте была бы плохой, потому что тогда я бы опирался на реализацию.
Я мог бы просто создать счет в БД и не беспокоиться обо всех насмешках и заглушках. Однако выполнение этого во всех спецификациях приведет к замедлению всего набора тестов.
Почему не интеграционный тест, чтобы вы могли реализовать весь стек? –