I’ve been a big fan of unit testing for a while (ever since the first releases of JUnit) but I haven’t been up-to-date with the latest technology. To be perfectly honest, I hadn’t expected anything else to appear after unit testing was first popularized. That’s why I was surprised to come across an off-hand reference to “Mock Objects” a few days back. Basically, Mock Objects are a true way to test an object “in a box” - ie: completely separate from the rest of your system.
What do I mean by this? Traditionally, when writing unit tests, you need to create a context for the object - in other words, an environment for the object to live within. Since many applications go through a lot of work to set up this environment, it can be difficult (and may require adding messy code) to create one solely for the purposes of a unit test.
Mock objects solve this problem by masquerading third-party objects within your system. You’re testing objects within a true black box. Any object that your testee calls can be replaced with an exact duplicate that looks like the object expected by the testee. There’s one essential difference - this object returns the specific values that you’ve previously determined to be useful for testing.
As an example, let’s say you’re testing an implementation of a database-backed object. Normally, the object interacts with some database class (in .NET, it might be an IDataAdapter object). Before mock objects, you’d have to create some sort of test database that can be used during the unit tests and populate it with some sort of test data. Now, you simply need to create a “mock” of an IDatabase object and tell it what to return for given functions. When your testee calls the method you’ve indicated to the mock object, the mock object will return the value you’ve specified! No database required - and no “backdoor coding”.
That’s not all. In a test, you generally have inputs and outputs. As an example, a network monitoring system may send an email if one of your systems goes down. You could write code in your object to check a “_doingTest” boolean flag and ignore the mail-sending routines - but that’s one more place where a bug could be introduced! To solve this, we now turn to the second part of Mock Objects - the “Expectation”.
Expectations are just that - you expect that your object will do something. Using the previous database example, I might expect that after it makes the first call, it uses the value returned from the call to make a second one. It’s the flip-side of white box testing - given these inputs, I expect these outputs.
If you’re interested in Mock Objects, check out the Mock Objects wiki. You’ll find some links to various Java Mock Object implementations. One caveat - I haven’t looked at any of these implementations, so I can’t make any recommendations.
If you’re a .NET programmer, take a look at NMock. There’s barely any documentation, but there are a couple of examples that illustrate how the system works. Check out the Weather example in their CVS repository for a head-start.
Happy testing!Read full post