2016-05-12 2 views
0

В настоящее время я работаю над командой, которая требует покрытия на 100% кода, и я не могу на всю жизнь получить этот единственный метод, чтобы получить текущее покрытие до 100%.Тестирование частного метода контроллера рельсов

У меня есть базовый контроллер, который выглядит так, как это происходит с несколькими другими контроллерами.

module Owners 
    module Pets 
    class BaseController < Owners::ApplicationController 
     private 

     def current_pet 
     current_owner.all_pets.find(params[:pet_id]) 
     end 
    end 
    end 
end 

Мои спецификации для этого контроллера выглядят следующим образом.

require 'rails_helper' 

Rails.describe Owners::Pets::BaseController, type: :controller do 
    routes { Owners::Engine.routes } 

    controller Owners::Pets::BaseController do 
    def index 
     current_pet 
    end 
    end 

    let(:user) { double :user, id: 1, owner: nil } 

    before { sign_in(user) } 

    before do 
    allow(request.env['warden']).to receive(:user).and_return user 
    allow(Owners::User).to receive(:find).with(user.id).and_return user 
    end 

    context 'with current owner and pet' do 
    let(:owner) { create :owner } 
    let(:pet) { create(:owner_pet, owner: owner) } 

    describe '#current_pet' do 
     before do 
     allow(controller).to receive(:current_pet).and_return pet 
     routes.append { get 'index' => 'owners/pets/base#index' } 
     end 

     it do 
     get :index 
     is_expected.to eq pet 
     end 
    end 
    end 
end 

ФПЭ неудача с ошибкой «Нет маршрут соответствует {: действие =>» индекс «: контроллер =>„владельцы/домашние животные/база“}» Routes.append следует добавить правильный маршрут, правильно ?

Обновление: перемещая мою линию routes { Owners::Engine.routes } над анонимным контроллером, она больше не вызывает ошибку, связанную с маршрутами. Однако теперь он сравнивает pet с фактическим классом контроллера. Выход слишком длинный для вставки здесь, но это по существу:

expected: #<Owners::Pet> 
got: #<#<Class:0x007fc65c860518>:0x007fc65f83a248> 

с целым рядом атрибутов и методов.

+0

Это действительно довольно творческий способ тестирования частного метода. У меня есть одно предложение: вам, возможно, придется утверждать об ответе '', поскольку синтаксис 'is_expected.to' утверждает на' subject', который, как представляется, является контроллером. Я не совсем уверен, как выглядит ответ, когда вы просто возвращаете объект AR, но, вероятно, вы можете понять это с помощью отладчика. – jfornoff

+0

Аналогичный вопрос [здесь] (http://stackoverflow.com/questions/4271696/rspec-rails-how-to-test-private-methods-of-controllers) –

ответ

1

Этот тест не имеет значения. Вы завершаете тот самый метод, который вы тестируете. Даже если тело метода #current_pet вызвало исключение, тест все равно пройдет.

Как правило, лучше избегать непосредственного тестирования частных методов. Вы должны иметь возможность протестировать этот метод косвенно через один из классов, который наследуется от Owners::Pets::BaseController.

0

При использовании синтаксиса it { is_expected.to ... } Rspec должен заключить, что такое «оно» на основе самого теста. Метод subject может использоваться для явного указания того, что такое «оно»; в случаях, когда отсутствует subject, Rspec будет создавать экземпляр нового экземпляра класса, который тестируется. В вашем случае это будет сам контроллер.

Попробуйте установить subject в явном виде в контексте блока #current_pet.

Например,

context 'with current owner and pet' do 
    let(:owner) { create :owner } 
    let(:pet) { create(:owner_pet, owner: owner) } 

    describe '#current_pet' do 
    before do 
     allow(controller).to receive(:current_pet).and_return pet 
     routes.append { get 'index' => 'owners/pets/base#index' } 
    end 

    # set this to whatever you want "is_expected.to" to be 
    subject { controller.current_pet } 

    it do 
     get :index 
     is_expected.to eq pet 
    end 
    end 
end 

обязательное Примечание: Я согласен с другими плакатами, что этот тест не очень полезен. Обычная мудрость заключается в том, чтобы тестировать только общедоступные методы (частные методы проверяются по их использованию в рамках общедоступного метода).

 Смежные вопросы

  • Нет связанных вопросов^_^