rubocop-rspec icon indicating copy to clipboard operation
rubocop-rspec copied to clipboard

StubbedMock: prefer `expect`

Open mockdeep opened this issue 3 years ago • 3 comments

Just upgraded and came across the new StubbedMock rule. I'd love to have a configuration that inverts the rule and prefers expect over allow. The reason for this is that I often come across tests where the implementation in the application code has changed such that the method is never called. I would rather have these cases fail the tests so that we also remember to remove the irrelevant mock from the tests.

mockdeep avatar Oct 24 '20 02:10 mockdeep

I understand what you mean, this in the best case renders this allow line useless. For those specs that have do depend on the internal implementation, I guess allow+expect is the way to go:

    a = []
    allow(a).to receive(:[]).with(1).and_return(2)
    expect(a).to receive(:[]).with(1)
    expect(a[1]).to eq 2

This makes me feel somewhat uncomfortable though, as it binds the implementation to the spec. From my point of view, it should either make an expectation on the result (what), or side effects (how), not both.

pirj avatar Oct 26 '20 08:10 pirj

FWIW, we've defined an invoke matcher that captures this as well:

expect { a[1] }
  .to invoke(:[]).on(a).with(1).and_return(2)

Though, like you say, we wouldn't normally test both the return value and the call. We'd normally avoid mocking at all, if we can reasonably.

mockdeep avatar Oct 26 '20 16:10 mockdeep

invoke 👍 There's a comparable send_message just in case.

pirj avatar Nov 02 '20 18:11 pirj