Wrangling Rhinoceri

I've been asked to help some teammates become more comfortable with Rhino.Mocks. I'll practice my explanations here, and y'all can offer guidance and ask clarifying questions if you're so inspired. I'll be glad for the help.

Rhino-what? What-mocks? What-what?
The domain we're discussing is unit testing, the code that developers write to verify the logic in their code. Rhino.Mocks is not a testing framework, but a mocking framework, which means it allows you to mock (simulate) parts of your application. You use it along with a testing framework like NUnit or MbUnit.

If you have written code without keeping an eye on testability, it is likely to be witheringly difficult to apply Rhino.Mocks after the fact. Life is simpler if you write the tests first, therefore Rhino.Mocks plays well with Test-Driven Development, which drives you to design your code in a testable way.

As far as what it is, Rhino.Mocks is a dll you include with your test project files. You create a reference to it from your test project, and it gives you some additional classes and methods you can use within your unit tests.

State-based and interaction-based tests
There are two main styles of unit tests, state-based and interaction-based, and each is useful for different things. With state-based, you set up some variables, run them through the methods you want to test, and then verify that their state has become what you expect. You use Assert statements to assert, "The state should be [this]. If not, fail the test." If you're testing an addition method, you can verify the state of the answer, as in, "I assert that 2 plus 2 should be 4."

Rhino.Mocks is used in interaction-based tests. Here you are verifying the interaction between your classes. For example, in a Model-View-Controller architecture, you could test your Controller's interactions with the Model and the View, as in, "I want to verify that, when the Controller is asked to display customers, it gets customers out of the data repository, runs the results through my CustomerFormatter class (I don't know, it's just an example), and sends them to be displayed on the user interface."

You have three interactions there, so you'll probably write three tests. You are not testing what comes out of the data repository, just that the Controller talked to it. In fact, you don't even need a real data repository for this test. If you could just simulate that repository in a way that let you verify it was called... This is what Rhino.Mocks gives you.

What next?
Martin Fowler has written a great article, Mocks Aren't Stubs. If this is your first introduction to Rhino.Mocks and mocking frameworks, perhaps not everything in that article will click with you. It is still worth reading now, and I'll link to it again in my next post. It wouldn't hurt to read Martin's article twice.

My next post will include why you would want to simulate classes instead of using the real thing. I also want to explain why you even want interaction-based tests. I have an intuitive sense of the value, but I am not yet good at articulating it. Feel free to chime in.

No comments: