Tuesday, January 4, 2011

To Rhino or not to Rhino?

 

I mean Rhino Mocks of course… (but you can change it to any mocking framework of your choice).

I believe one of the objective in writing good code is writing readable code, and our coded unit test are in code so that as well should be readable.

In many cases I found the readability of tests using Rhino Mocks for everything is slim to none.

Lets look at the following code example:

When a book is added to the system it uses BookDal to add the book, AuthorDal to get the author id and if he doesn't exist to add him, PublicationDal similar to  AuthorDal but with publications.

BookBL's method Add(Book book) looks something like:

Public void Add(string name, string author, MapPoint currentLocation)

{

                var  author =

}

Using Rhino Mocks to test everything here will look like:

[TestMethod]

Public void Add_ValidBook_BookAddedToDb()

{

                Using(_mock.Record())

                {

                               

                }

}

So where do I believe you should use Rhino Mocks:

1.       When you don't care about the outcome of the method.

2.       When you have tests covering the operation of the method.

3.       When you receive data from an outside source in the method (such as MSMQ).

4.       When the using(_mocks.Record()) statement is unreadable – contains too many methods with too many constraints.

5.       When if you change the code you don't need to change the recording.

After all this rules I believe you cannot use Rhino Mocks to mock any work with the DB, because:

1.       You do care about the outcome, this is one of the end result of calling your method.

2.       If the method update/selects/insert/delete to many tables you will end up with a monster that is both unreadable and any changes to your tests will cause your tests not to pass.

For example:

If my code instead of updating did a:

Get+change => delete from Db => insert the changed data

And then I refactored it to simply:

Update

The end result in the DB will be the same but the recording of the mocks will have to change.

 

What do I propose?

If you wrote/use a Dal framework than:

1.       You must write integration coded unit tests to that framework.

2.       You must write a Dal framework that works with an in memory DB or make sure the Dal framework works with in memory DBs.

 

The above example with such a framework:

 

 

//TODO: Add Resources

//TODO: Complete the examples

//TODO: Post the Examples before this post