<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
<div name="messageBodySection">
<div dir="auto">I guess when you've got service A calling another service, the unit tests for A are really only validly checking for two different things:<br />
<br />
1) That you're passing the expected values to service B depending on different scenarios that service A finds itself in<br />
2) The service A correctly responds to whatever return values service B might pass back, which might include raised exceptions.<br />
<br />
If you decouple those two sets of expectations from each other in A's unit tests, you're reducing service A's knowledge about how service B works.<br />
<br />
When it comes to actually verifying that the calls are valid, that's trickier.<br />
If you're creating doubles to act as stand-ins for real service B, RSpec offers you verifying doubles in the shape of class_double and instance_double. They only verify that any methods you stub are present on the class and don't verify any arguments, though.<br />
<br />
Could you establish some sort of factory system in your test suite for your doubles, so that you define them all in one place rather than dotted throughout your tests? That way, if you make changes to service object B you'd get in the habit of updating the doubles at the same time, a syou might for, say factory_bot factories when you update. models?<br />
<br />
Would be interested to hear thoughts from others…</div>
</div>
<div name="messageReplySection">On Jun 6, 2024 at 11:56 AM +0100, Patrick Gleeson <patrick.c.gleeson@gmail.com>, wrote:<br />
<blockquote type="cite">
<div dir="ltr">Hi LRUG,
<div><br /></div>
<div>I've been bitten by bad unit tests in the past (mostly ones I've written myself), and lean towards integration tests (a la <a href="https://x.com/rauchg/status/807626710350839808">https://x.com/rauchg/status/807626710350839808</a>) when given the choice. But I want to believe good unit tests are achievable. A problem I often encounter is something like this:</div>
<div><br /></div>
<div>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.</div>
<div><br /></div>
<div>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?</div>
<div><br /></div>
<div>Patrick</div>
<div><i>Mediocre developer. Failed composer. Fledgeling novelist (<a href="https://bedfordsquarepublishers.co.uk/book/hattie-brings-the-house-down/">https://bedfordsquarepublishers.co.uk/book/hattie-brings-the-house-down/</a>).</i></div>
<div><br /></div>
</div>
_______________________________________________<br />
Chat mailing list<br />
Chat@lists.lrug.org<br />
Archives: http://lists.lrug.org/pipermail/chat-lrug.org<br />
Manage your subscription: http://lists.lrug.org/options.cgi/chat-lrug.org<br />
List info: http://lists.lrug.org/listinfo.cgi/chat-lrug.org<br /></blockquote>
</div>
</body>
</html>