我有一个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: # received unexpected message :[]= with (:cart_id, 123)
如何解决这个问题?我试着写一些expect
expect(session).to receive(:[])
但它不起作用,它仍然是同样的错误
问题是:
收到一条消息
这不是预期的
所以,你可以做两件事来摆脱这个消息:
不发送消息或
告诉双人期待这条消息
第一个很简单:只需删除第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))
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。