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?

3 Responses to “Talk you like mock”

  1. paulwilson Says:

    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.

  2. dchelimsky Says:

    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?

  3. Brian Marick Says:

    I bet “expect” would appeal to more people than “behold!”. “Behold!” seems unserious.

Leave a Reply

You must be logged in to post a comment.