[LRUG] Joined-up unit tests
Kozubink rejestla
rejestlakozubink at gmail.com
Thu Jun 6 13:02:04 PDT 2024
okay
On Thu, Jun 6, 2024 at 3:32 PM Tom Chipchase via Chat <chat at lists.lrug.org>
wrote:
> First of all, I wouldn't get too hung up on deciding that because you're
> doing unit testing, you need to mock B. If its not slow, not difficult to
> set up in a way that it will return valid responses, and not making
> requests to external services you don't want to (or can't) do during your
> CI pipeline, you can just call a real B. (not an exhastive list, there are
> other valid reasons for mocking).
>
> Secondly, you probably don't want to do `expect(B).to
> receive(:call).with(x).and_return(y)`. Its conflating two things. If the
> point of the test is that A does some stuff, and as a result calls B, and
> you're test is asserting that B is called with some parameters, it doesn't
> matter what the return object is. If A calls B to get `y` and then do some
> other things with it, you don't need to `expect` it to happen; something
> else in your test should fail if it doesn't, so you just need to `allow`
> instead of `expect`.
>
> Pact has already been mentioned, and that is the path I would go down. I'm
> not aware of a similar tool that works at the rspec mock level, but you
> could probably get something close. The key point is that everywhere you
> have `allow(B).to receive(:call).with(x).and_return(y)`, there should be a
> corresponding test that asserts that if B is called with x, it does in fact
> return y. If you combined that with a previous suggestion of defining all
> your mocks in one place, and using rspec's shared_examples, you could run
> the same shared example against the real B, and the double of B to ensure
> they behave the same (or close enough that the tests using your doubles
> don't care about the difference). The one bit of discipline required would
> be that if you mock something new, you need to write a spec too.
>
> Lastly, this is a lot easier when the code your testing has been written
> with this approach in mind from the start. A key thing with pact is that
> the consumer side is written first, and that's how I'd approach this too.
> If you're just adding mocks to existing specs in order to isolate them,
> you'll just end up with very brittle specs.
>
> On Thu, 6 Jun 2024, at 11:51 AM, Patrick Gleeson wrote:
>
> Hi LRUG,
>
> I've been bitten by bad unit tests in the past (mostly ones I've written
> myself), and lean towards integration tests (a la
> https://x.com/rauchg/status/807626710350839808) when given the choice.
> But I want to believe good unit tests are achievable. A problem I often
> encounter is something like this:
>
> Service A calls service B. The unit tests for service A mock service B
> using statements like "expect(B).to receive(:call).with(x).and_return(y)".
> But in reality (due to refactors over time or misunderstandings between
> teammates), if you passed x to service B you'd get a return value of z, or
> it would raise an ArgumentError. So the unit tests for A are only passing
> because they're describing an impossible situation.
>
> Are there any good patterns for constraining the arguments and return
> values stated in mocks somehow? I'd love it if something would check that
> the inputs and outputs I specify when mocking service B have been "proven"
> to be accurate in my unit tests for B. That way my unit tests could give me
> some of the benefits of (slower, unwieldier) integration tests "for free".
> Or am I being hopelessly naive and misguided here?
>
> Patrick
> *Mediocre developer. Failed composer. Fledgeling novelist
> (https://bedfordsquarepublishers.co.uk/book/hattie-brings-the-house-down/
> <https://bedfordsquarepublishers.co.uk/book/hattie-brings-the-house-down/>).*
>
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> Archives: http://lists.lrug.org/pipermail/chat-lrug.org
> Manage your subscription: http://lists.lrug.org/options.cgi/chat-lrug.org
> List info: http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
>
> _______________________________________________
> Chat mailing list
> Chat at lists.lrug.org
> Archives: http://lists.lrug.org/pipermail/chat-lrug.org
> Manage your subscription: http://lists.lrug.org/options.cgi/chat-lrug.org
> List info: http://lists.lrug.org/listinfo.cgi/chat-lrug.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lrug.org/pipermail/chat-lrug.org/attachments/20240606/8a74bcc4/attachment.htm>
More information about the Chat
mailing list