dam*_*anw 5 ruby rspec ruby-on-rails ruby-on-rails-5
我对 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
binding.pry
session[:cart_id]
=> 574
Run Code Online (Sandbox Code Playgroud)
session[:cart_id] = 123
RSpec::Mocks::MockExpectationError: #<InstanceDouble(session) (anonymous)> received unexpected message :[]= with (:cart_id, 123)
Run Code Online (Sandbox Code Playgroud)
如何解决这个问题?我尝试写一些expect
expect(session).to receive(:[])
Run Code Online (Sandbox Code Playgroud)
但还是不行,还是同样的错误
该消息告诉您,您的替身收到了[]=带有参数的消息:cart_id,123但没有预料到。
让我们应用一些基本逻辑。问题是:
因此,您可以采取两件事来消除该消息:
第一个很简单:只需删除第 14 行,其中显示“ session[:cart_id] = current_cart.idsince that is the only place you are Calling” []=。但是,我认为这不是您想要做的。
第二点也很容易。有一个名为的方法expect可以让你告诉替身期待某个消息。所以,我们需要做的就是建立一个期望。
良好的失败消息在测试框架中非常重要,值得庆幸的是,RSpec确实有良好的失败消息。失败消息应该告诉您如何继续进行测试,并且您引用的消息包含我们需要的所有信息:
session)[]=):cart_id和123)我们所要做的就是,不假思索,直接复制并粘贴以下信息:
expect(session).to receive(:[]=).with(:cart_id, 123)
Run Code Online (Sandbox Code Playgroud)
或者,如果我们希望我们的测试不那么脆弱并且不对 进行硬编码123,我们也可以这样做:
expect(session).to receive(:[]=).with(:cart_id, instance_of(Integer))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7334 次 |
| 最近记录: |