控制器规范:expect(controller).to receive(:create) 阻止执行 #create 操作

Jos*_*eim 2 controller rspec ruby-on-rails mocking

我有以下行动:

def create
  binding.pry
  @finding.save
  respond_with @project, @finding
end
Run Code Online (Sandbox Code Playgroud)

运行以下测试时...

it 'balances the consecutive numbers', focus: true do
  expect {
    post :create, params: {...}
  }.to change { Finding.count }.from(0).to 1
end
Run Code Online (Sandbox Code Playgroud)

...我首先binding.pry显示控制台(证明该#create操作实际已执行),然后规范通过:

Finished in 4.24 seconds (files took 5.31 seconds to load)
1 example, 0 failures
Run Code Online (Sandbox Code Playgroud)

现在当我添加一个expect(controller).to receive(:create)...

it 'balances the consecutive numbers', focus: true do
  expect(controller).to receive(:create) # This is new!

  expect {
    post :create, params: {...}}
  }.to change { Finding.count }.from(0).to 1
end
Run Code Online (Sandbox Code Playgroud)

...并再次运行测试,我立即显示了此规范失败结果:

expected result to have changed from 0 to 1, but did not change
Run Code Online (Sandbox Code Playgroud)

当消除change { ... }期望...

it 'balances the consecutive numbers', focus: true do
  expect(controller).to receive(:create)

  post :create, params: {project_id: @project.id, finding: {requirement_id: @requirement.id}}
end
Run Code Online (Sandbox Code Playgroud)

...它再次通过:

1 example, 0 failures
Run Code Online (Sandbox Code Playgroud)

但是,仍然没有调用binding.pryin #create

那么这里发生了什么?expect(controller).to receive(:create)似乎以某种方式阻止了实际#create操作的执行!这不是我想要的。我希望它像往常一样执行。

我在这里做错了什么?

cef*_*edo 5

当你使用expect().to receive()真正的方法时被抑制......它只是验证是否按预期调用了某些东西......

当我们想要测试我们无法控制答案或我们想要模拟答案是否被调用时,我们通常会使用它。

如果你想检查是否有东西被调用,并运行原始文件,你应该使用:

expect(something).to receive(:some_method).and_call_original
Run Code Online (Sandbox Code Playgroud)

https://relishapp.com/rspec/rspec-mocks/v/3-5/docs/configuring-responses/calling-the-original-implementation