Talk you like mock
UPDATE: Judging from email, I wrote this badly. Ignore the bit about assertEquals
. My point is that I want to write mock tests the way I talk, which is “when this method executes, it calls these other methods in such and so a way” rather than “expect these other methods to be called in such and so a way when this method executes”. Since, in my speech, I describe the action before its effects, I want mock tests to do that too. So I made up a notation and seek comments.
I think we all know that the order of arguments is wrong in JUnit’s assertEquals
. If you talked like JUnit wants you to, you’d say things like “After the calculation I’ve just described, 23 is the resulting azimuth.”
It’s not so big a deal that your order of thinking about a truth statement doesn’t match the order in which you have to type it. Probably no more than one in a billion people is driven homicidally insane by the accumulated weight of such grating little annoyances. And there’s nothing we can do about it now.
Let’s move on to mocks. Here’s a test method (with some long lines edited to fit):
def test_checker_normally_checks_network_once
checker = testable_checker # creates checker
# using mocks.
@network.should_receive(:ok?).once.
with(”url”).
and_return(true)
checker.check(”url”)
end
Reading that aloud would sound something like this:
“The network gets asked if some URL is OK once when…
… wait for it…
… wait for it…
… wait for it…
… the checker is invoked with that URL.”
This is, again, not the way people talk. You might not be able to do anything about the problem in Java, but in a Real Language (meaning: one with lambda), you can. So I’ve today started writing my mock tests like this:
def test_checker_normally_checks_network_once
checker = testable_checker
during {
checker.check(”url”)
}.behold! {
@network.should_receive(:ok?).once.
with(”url”).
and_return(true)
}
end
The “behold!” is a little hokey; I couldn’t think of a good connecting word. But I do think this reads better. Does it read better to you?
Notes:
-
I don’t use mocks that much. This style may not work in complicated situations.
-
Surely someone’s done this before? Who?
October 2nd, 2007 at 2:15 pm
One of the reasons I gave up JMock was the unnatural order of statements. I soon got used to writing the expectations first, but never got used to reading them in that order on returning to a test. This is much better.
I no longer use mocks, but suspect that should the situation be too complicated to use this style then that could be telling you something about the code.
As for “behold!”, I sort-of like it: it adds energy to the test. I think “the” might work, if you fancied a more subdued style.
October 2nd, 2007 at 2:40 pm
The issue has come up on the rspec lists before, but I’m not sure if a reasonable sounding solution ever came up. This seems to be it.
As for word choice, behold “expect”
during {
checker.check(”url”)
}.expect {
@network……
}
WDYT?
October 3rd, 2007 at 9:40 am
I bet “expect” would appeal to more people than “behold!”. “Behold!” seems unserious.