我有一个问题与rspec行为。我试图写测试的服务,我使用session
,为读取一些值,并覆盖此值。
比如我想测试的
class CurrentCartService
attr_reader :user, :session
def initialize(user, session)
@user = user
@session = session
end
def cart_id
{ id: session[:cart_id] }
end
def assigne_cart_to_session
session[:cart_id] = current_cart.id
end
字符串spec
个
describe CurrentCartService do
let(:current_user) { user }
let(:session) { double('session') }
let!(:cart) { create(:cart) }
subject { described_class.new current_user, session }
before do
allow(session).to receive(:[]).and_return(cart.id)
end
describe '#call' do
context 'when user is not signed' do
let(:user) { nil }
it { subject.call }
end
end
end
型binding.pry
个
session[:cart_id]
=> 574
session[:cart_id] = 123
RSpec::Mocks::MockExpectationError: #<InstanceDouble(session) (anonymous)> received unexpected message :[]= with (:cart_id, 123)
的字符串
如何解决这个问题?我试着写一些expect
expect(session).to receive(:[])
型
但它不工作,它仍然是相同的错误
2条答案
按热度按时间lf5gs5x21#
该消息告诉你,你的替身收到了带有参数
:cart_id
和123
的消息[]=
,但没有预料到它。让我们应用一些基本的逻辑。问题是:
1.接收消息
1.出乎意料的
所以,有两件事你可以做,以摆脱消息:
1.不发送消息或
1.告诉替身等消息
第一个很简单:删除第14行
session[:cart_id] = current_cart.id
,因为这是你唯一调用[]=
的地方。然而,我不认为这是你想做的。第二个方法也很简单,有一个叫做
expect
的方法,它允许你告诉一个double去期望某个消息,所以我们需要做的就是设置一个期望值。好的失败消息在测试框架中非常重要,谢天谢地,RSpec * 确实有好的失败消息。失败消息应该告诉你如何继续你的测试,你引用的消息包含了我们需要的所有信息:
session
)[]=
):cart_id
和123
)我们所要做的就是,甚至不用考虑它,字面上只是复制和粘贴这些信息:
字符串
或者,如果我们希望测试不那么脆弱,而不是硬编码
123
,我们也可以这样做:型
egmofgnx2#
我不明白你选择的设计,所以我只回复你得到的错误。
您允许
session
接收:[]
。错误是session
接收了:[]=
。因此,您可以允许
session
接收:[]
字符串
注意:我不会使用
expect
,因为它仅仅是为了设置测试期望,而不是测试,这是你想用allow
实现的。