UnitTests in WCSF : Do Mocks provide "real" value?

Topics: Web Client Software Factory
May 28, 2007 at 6:32 AM
I have been evaluating WCSF for use withing my organization. At my company we use CI and TDD practices and I see the value in unit tests and code coverage analysis, etc. etc. I have never been a real fan of MVP / MVC because of all of the moving parts compared to what "really" gets re-used. A Microsft MVP told me that the "real" purpose of the MVP & MVC patters was to allow us to unit test more of the code and to allow us to switch between WinForms, WebForms, and CompactFramework with minimal modifications to code. So, once again, here I am reviewing the latest and greatest from the P&P team.

In my review of the Global Bank Commercial EBanking solution, I see that mocks are used heavily. I am not too sure if I am missing the point but it seems to me that mocks are just testing the published / public interfaces of the objects being created in WCSF (i.e., views, presenters, controllers, services, module initializers, etc.).

Assuming that this observation is correct, I have concluded that the "real" functionality that is being delivered is never tested with mocks. Is this a correct conclusion? The reason that I have come to this conclusion is that I havent found many unit tests that deal with the "real" code, (i.e. the functional code that lives in the NON-mock classes).

So I guess my real question is this... aside from proving that you have invoked the methods and members of your mock classes, how valuable are unit tests that work with mocks? My reasoning behind this question is that, just because our executing code hits the mock classes, if the code that lives in the real object doesnt work then we dont have functionality that is deliverable.

My second question is this... should we be using unit tests that work with the "real" code in addition to unit tests that work with mock objects?

Thanks for your guidance, opinions, and comments.
Jun 3, 2007 at 4:27 AM
My attempt to address this starts with this question: what is a unit?

Ideally, we'd like to test our classes in isolation. Consider the model class. Usually testing model is pretty easy - you just poke it with a stick (call methods) and see what flies out (return values, exceptions, events, etc.) Except - what if the model logic calls into a database, or writes to a file, or updates a log, or...

We want to test just the model, not model + database + file writer + logger + ... . So, we factor out those external dependencies into their own objects, and then we introduce stubs, fakes, or mocks as needed to provide enough implementation for the model to respond to the test we're writing.

This is particularly important in the case of the presenter. The presenter's primary job is to act as a mediator - event fired here results in method call there. In this case, the mocks are needed because "testing the published / public interfaces of the objects" is the whole point. We want to make sure that the presenter fires the right things at the right time, but we don't want to hook up the model + database + file writer + ... as well to make that happen. Mocks give us a way to test the behavior of the presenter while still being a UNIT test.

I am not saying in any way that you should not write tests that exercise the whole system. However, that's a integration or functional test, not a unit test, and needs to be considered separately. A unit test needs to run fast, require no preconditions (like a database setup or a data file present), and be idempotent (doesn't perturb persistent system state). Integration tests don't have these limitations, but they also don't get run every five minutes.

Having said that, of course not everyone lives up to the ideals every time. We are constantly trying to improve both our processes and our tests and our test coding, but for some reason people keep making us stop and ship stuff instead. ;-)

I hope this helps,

-Chris
Jun 3, 2007 at 4:30 AM
Oh, one more thing I forgot - to actually answer your question. :-)

Are unit tests using mocks valuable? Yes. And all your functionality should get tested, just not all in one test or test fixture. So the presenter would have a set of tests that mock out model and view, the model would have another set of tests that mock out its dependencies, etc. So over the entire test suite, every method should have been exercised, and so the "real" functionality does get tested. Just not all at once.

The view typically doesn't get tests, but that's because testing UI is rediculously hard and that's why we make the views as stupid as possible. If the code's too simple to break, you don't need to test it.

-Chris
Jun 4, 2007 at 10:24 AM
Edited Jun 4, 2007 at 10:26 AM

ctavares wrote:
The view typically doesn't get tests, but that's because testing UI is rediculously hard and that's why we make the views as stupid as possible. If the code's too simple to break, you don't need to test it.

-Chris


I've had some success using WatIn for UI unit testing...

http://watin.sourceforge.net/
Jun 4, 2007 at 10:26 AM
Also, if you are going to use mocks, why not look mocking frameworks such as NMock or RhinoMocks.

It certainly cuts down on the amount of work required to actually create the mocks in the first place...