剔除 class 的实例以测试作为属性给出的回调

Stubbing out an instance of a class to test a callback given as an attribute

我正在尝试使用 Rspec 3.9 测试 proc 中的一行代码(请参阅下面的代码片段中的 proc { |message| flash[:notice] << message }),但我似乎无法存根出实例来做我想做的事。

给定以下控制器和测试,我怎样才能去掉控制器中给定的 CreateAccount 和 运行 on_success 属性?

这是控制器文件

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

        redirect_to action: :index
    end
end

这是Rspec测试文件

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 个可行的解决方案,但我想知道是否有更简洁的方法

注意:控制器和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