我的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(:[])
但是它不起作用,仍然是相同的错误
答案 0 :(得分:0)
该消息告诉您,您的双打收到了带有参数[]=
和:cart_id
的消息123
,但没想到。
让我们应用一些基本逻辑。问题是:
因此,您可以做两件事来摆脱该消息:
第一个很简单:只需删除第14行显示session[:cart_id] = current_cart.id
,因为这是您唯一呼叫[]=
的地方。但是,我认为这不是您想要做的。
第二个也很容易。有一种称为expect
的方法,该方法使您可以告诉双精度字符期望某条消息。因此,我们要做的就是建立期望。
好的故障消息在测试框架中确实很重要,并且值得庆幸的是,RSpec 确实具有好的故障消息。失败消息应该告诉您如何继续进行测试,并且所引用的消息包含我们需要的所有信息:
session
[]=
):cart_id
和123
)我们所要做的就是根本不考虑它,只是复制并粘贴以下信息:
expect(session).to receive(:[]=).with(:cart_id, 123)
或者,如果我们希望测试不那么脆弱并且不对123
进行硬编码,我们还可以执行以下操作:
expect(session).to receive(:[]=).with(:cart_id, instance_of(Integer))