Заглушка экземпляра класса для проверки обратного вызова, заданного как атрибут - PullRequest
0 голосов
/ 21 февраля 2020

Я пытаюсь протестировать строку кода в proc см. (proc { |message| flash[:notice] << message } в фрагменте кода ниже), используя Rspe c 3.9, но я не могу заглушить экземпляр, чтобы сделать то, что я хотеть.

С учетом следующего контроллера и теста, как я могу заглушить CreateAccount и запустить атрибут on_success, указанный в контроллере?

Вот файл контроллера

class AccountsController < ApplicationController
    def create
        CreateAccount.new(
          on_success: proc { |message| flash[:notice] << message }
        ).process

        redirect_to action: :index
    end
end

Вот тестовый файл Rspe c

describe AccountsController, type: :controller do
    describe 'POST #create' do
        subject(:create_action) { post :create, id: 1 }

        let(:success_message) { 'Success!' }

        context 'when created account successfully' do
            it { is_expected.to redirect_to action: :index }
            it do
                create_action
                expect(flash[:notice]).to include success_message
            end
        end
    end
end

Причина, по которой я хочу это сделать, состоит в том, чтобы отделить задачи от контроллера до объекта CreateAccount. Это не должно иметь значения, но пока это CreateAccount объект.

class CreateAccount
    def initialize on_success: proc { |_| }
        @on_success = on_success
    end

    def call
        # Do some meaningful work
        success_message = 'Meaningful message'

        @on_success.call(success_message)
    end
end

1 Ответ

0 голосов
/ 21 февраля 2020

Мне удалось найти 1 решение, которое работает, но я хотел бы знать, есть ли более чистый способ

Примечание: классы контроллера и CreateAction остаются прежними.

describe AccountsController, type: :controller do
    describe 'POST #create' do
        subject(:create_action) { post :create, id: 1 }

        context 'when created account successfully' do
            let(:dummy_class) do
                Class.new(CreateAction) do                
                    def call
                        @on_success.call(self.class.message)
                    end

                    def self.message
                        'Success!'
                    end
                end     
            end

            before { stub_constant 'CreateAction', dummy_class }

            it { is_expected.to redirect_to action: :index }
            it do
                create_action
                expect(flash[:notice]).to include dummy_class.message
            end
        end
    end
end
...