Your Unit Tests Should Mind Their Own Business

As the unit testing debates continue on my project, I can't help but noticing that people are spending all sorts of time pontificating over the right way to unit test, without stepping back to consider what they're trying to achieve with unit testing. And because they don't know where they're going, they're not reaching any conclusions on how to get there. Sound familiar?

There are actually a number of fabulous reasons for doing unit testing:

1. They help us think about our design in a way that we might not otherwise.
2. They lead to cleaner code because it's often easier to re-factor our code to be more testable then it is to write unit tests that exercise obfuscated or otherwise hard to access code.
3. They validate that our modules are behaving correctly.
4. They provide a safety net to ensure our existing modules continue to function properly as our application evolves.

These aren't all intuitive and so a lot of people will only consider #3 when they think about unit testing. And yet, what's interesting is that #3 typically provides the smallest return on our unit testing investment because we tend to find WAY more defects through #1 and #2 as we work out how to develop our tests, and then of course in #4 as we continue to change our code over the application's lifetime. And, unfortunately, by focusing only on #3, it can lead us to make some faulty decisions when we try to reason about the best way to do unit tests.

Article Type: 
Opinion/Editorial
0
Average: 3.5 (2 votes)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Kevin Conaway replied on Sat, 2008/07/19 - 8:41am

Well said. 

 You made a nice case as to why its important to test the result of calling your class, not how your class computed that result.  That is an easy trap to fall into when testing with mock objects, especially when mocking the Servlet API

haxrchick replied on Sun, 2008/07/20 - 1:17pm

Thanks for your comment, Kevin.  I must admit I'm a bit surprised that I haven't heard from anyone using mocks as to why they're the right way to go even if they do couple your tests with your implementation. 

Anyone out there using mock objects that can speak to the other side of this argument?

Kevin Conaway replied on Sun, 2008/07/20 - 1:48pm in response to: haxrchick

[quote=haxrchick]

I must admit I'm a bit surprised that I haven't heard from anyone using mocks as to why they're the right way to go even if they do couple your tests with your implementation.

[/quote]

I don't know that Mocks are the right way so much as sometimes they're the only way.

Years ago when people would test their servlets or Struts actions, you had to interact with the HttpSession or HttpServletRequest at some point.  The choices were:

1.) Test nothing

2.) Refactor away your code that touches the Servlet API

3.) Mock the Servlet API

 Taking option 2 will eventually bring you back to a choice between 1 and 3.

partyzant replied on Mon, 2008/07/21 - 5:46am in response to: haxrchick

[quote=haxrchick]

Thanks for your comment, Kevin. I must admit I'm a bit surprised that I haven't heard from anyone using mocks as to why they're the right way to go even if they do couple your tests with your implementation.

Anyone out there using mock objects that can speak to the other side of this argument?

[/quote] You should just verify what is important. If you supply a MockStudent, method call order is probably irrelevant, but if it's, say, a MockTransaction, you want to make sure that the transaction is committed after all data is written out and only then.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.