CITCON Paris 2009: Mock objects

Interfaces

During the session on mock objects there was a digression about interfaces. I have seen too often interfaces in a way that I don't like. I will use the same example as Eric:

Let's say that you have a FileManager, providing some services to manage files I suppose 😉, you may have an interface called IFileManager. And usually there is only one implementation of IFileManager which is FileManager.

I think this is wrong for at least two reasons:

  • Usefulness. If there is only one implementation, why do you need an interface?
  • Naming. The interface name should represent the "role", so FileManager is suitable for the interface name, IFileManager has no meaning. Then the implementation should reflect what kind of implementation you have, like LocalFileManager, DistributedFileManager or a DummyFileManager for your tests (but not an ugly FileManagerImpl).

So usually, when I see a software with that kind of 1 to 1 relationship between interface and implementation and using bad names, it raises a warning light in my head, telling me that the person who wrote that code did not really know what he was doing (only applying some old and bad coding rules without trying to understand why it was useful for). As Antonio says, prefix "I" for interface and suffix "Impl" for implementations are signs of code smell.

I even have seen some interfaces with only one or two methods, the implementation had a lot more methods… and the concrete class was directly used in other classes… so yes, very useful interface 😕.

Sometimes, when writing tests, I need to mock some classes that I haven't defined any interface for… and since several mock libraries are able to mock concrete classes I still not extract any interface.

I like simple classes, with simple roles, so mostly all public methods (except constructor and setters) are the "implied" interface.

So my point on interfaces is "use an interface only when you really need it" (that reminds me YAGNI):

  • when you need several implementations of a given "role",
  • when defining some "ability" (sorry I didn't find the right term) like Clonable, Closable, Comparable, Serializable, Anything-able (if you can add "able" at the end, it's a good sign that you might be able to extract an interface for that 😉).

Mock objects

So yes, we also spoke about mock objects. Steve Freeman was trying to explain us some stuff, I have the feeling that there was something in his speech that was enlightening but I didn't really get it (that's why it's only a feeling for the moment).

What I remember is that, when writing tests:

  • mock the collaborating classes that change the outside world,
  • use stubs, dummy implementations, etc. otherwise.

I don't fully understand the reason yet. But something I learn recently and that was says during the session: mock only the code you own, don't mock external resources.

So for instance, if you have a Customer object, a table full of customers in your database, don't try to mock JDBC classes like Connection, ResultSet and so on. Create a class accessing the data, let say CustomerDAO (I don't like the name, but hey, it's only an example), and then you can mock your CustomerDAO in your software.

I imagine that CustomerDAO will then be tested in integration tests (it's a class using external software/server/stuff right? Can't really unit test it (except maybe some data storage specific logic I may have to write in it)).

Anyway, it was an interesting session.

Misc

Books recommended during the session:

Frameworks:

  • jMock (the framework I usually use)
  • EasyMock
  • Mockito (more recent, I started using it a bit at work a week ago, looks quite nice)

Comments Add one by sending me an email.

  • From Laurent ·
    Still using Mockito, and I love it, really good framework.