On stubbing queries

64 views
Skip to first unread message

Daniel Wellman

unread,
Oct 22, 2015, 7:25:11 PM10/22/15
to growing-object-o...@googlegroups.com
Hi all,

I've been thinking about using mock objects and the advice of "Expect commands, stub queries" and had a question for the group.

When I explain why I follow this rule it's because:

I want the test to communicate the difference between commands and queries to future readers so they understand which parts are essential. That is, commands are usually the most important part, and queries are a way to provide information to the code under test.

... But the object could be free to obtain that information in any way it wants. If the production code changed to get that query information from another collaborator, or manufactured the data itself, the test should not fail on an unused query ("allowing()") test double setup.

If this scenario happened though, it probably would mean that an abandoned "allowing()" clause could still exist in the test, leaving clutter and noise for the next reader. You need to remember to delete that unused allowing clause to keep the code clean.

So if you want to keep your tests clean of unused test double setup, you'll need to change (delete) that line of code from your test when the production code changes.

... So then I'm left with "Expect commands and stub queries is primarily a communication tool to the test reader."


What am I missing, if anything?

How do other folks on this list explain this distinction?

Thanks!

Cheers
Dan


Steve Freeman

unread,
Oct 23, 2015, 7:12:08 AM10/23/15
to growing-object-o...@googlegroups.com
Yes, it's mainly a communication tool. allowing() has advantages in some tests where common queries can be refactored to the test setup.

All of this tends to be less of a problem where there's an explicit interface to the external resource that describes just what the code under test needs from its environment. There'll probably be more flux if you're mocking someone else's API.

Over time, I find myself having fewer, more relevant, collaborators than I used to, so this becomes less of a problem.

S

Daniel Wellman

unread,
Oct 23, 2015, 9:21:13 AM10/23/15
to growing-object-o...@googlegroups.com
Thanks for your reply, Steve. Some follow up inline:

> On Oct 23, 2015, at 7:12 AM, Steve Freeman <st...@m3p.co.uk> wrote:
>
> All of this tends to be less of a problem where there's an explicit interface to the external resource that describes just what the code under test needs from its environment.

Said another way -- as interfaces stabilize, you end up with less rippling changes to collaborators that make the _test double library runtime differences (I.e. Fail the test or not) between expects and allowing_ significant. Is that what you meant?

> Over time, I find myself having fewer, more relevant, collaborators than I used to, so this becomes less of a problem.

Did you mean "Over my career, I've noticed..." or "As a code base evolves (healthily)..." Or something else? (Let me guess: Both?) :)

And what is it you have been doing to get to this point?


And after I wrote my message, I realized another reason I prefer stubbing queries: If I use a stub, I'll still need to clean up the test when I'm done refactoring, but allowing clauses are less likely to interrupt my state of flow with a failed test. I may only save a matter of seconds or minutes, but I prefer not to be interrupted with unnecessary failures while I'm refactoring. When my head is clear and the tests are green, then I'll clean up the tests. Call it "reducing failure-induced stress while trying to work predictably."


Thanks!

>
> S
>
>
>> On 23 Oct 2015, at 00:25, Daniel Wellman <etl...@gmail.com> wrote:
>> I've been thinking about using mock objects and the advice of "Expect commands, stub queries" and had a question for the group.
>>
>> When I explain why I follow this rule it's because:
>>
>> I want the test to communicate the difference between commands and queries to future readers so they understand which parts are essential. That is, commands are usually the most important part, and queries are a way to provide information to the code under test.
>>
>> ... But the object could be free to obtain that information in any way it wants. If the production code changed to get that query information from another collaborator, or manufactured the data itself, the test should not fail on an unused query ("allowing()") test double setup.
>>
>> If this scenario happened though, it probably would mean that an abandoned "allowing()" clause could still exist in the test, leaving clutter and noise for the next reader. You need to remember to delete that unused allowing clause to keep the code clean.
>>
>> So if you want to keep your tests clean of unused test double setup, you'll need to change (delete) that line of code from your test when the production code changes.
>>
>> ... So then I'm left with "Expect commands and stub queries is primarily a communication tool to the test reader."
>>
>>
>> What am I missing, if anything?
>>
>> How do other folks on this list explain this distinction?
>
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "Growing Object-Oriented Software" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to growing-object-oriente...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages