我正在尝试使用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
我设法找到一种可行的解决方案,但我想知道是否有更清洁的方法
注意:控制器和CreateAction
类保持相同。
describe AccountsController, type: :controller do
describe 'POST #create' do
subject(:create_action) { post :create, id: 1 }
context 'when created account successfully' do
class DummyAction < CreateAction
MESSAGE = 'Success!'
def call
@on_success.call(MESSAGE)
end
end
before { stub_constant 'CreateAction', DummyAction }
it { is_expected.to redirect_to action: :index }
it do
create_action
expect(flash[:notice]).to include DummyAction::MESSAGE
end
end
end
end