views:

494

answers:

3

My application is using Rhino.Commons - NHRepository and UnitOfWork. I like the With.Transaction() syntax for transactions and have been using it for some time.

But I ran into a problem - how do I mock a UnitOfWork for testing? Especially this is causing trouble for me:

With.Transaction(() => Repositories.TwinfieldSpooler.Update(spool));

I can mock repositories with Rhino.Mocks, but how can I easily mock UnitOfWork for this kind of code?

+3  A: 

With.Transaction uses UnitOfWork.Current property. UnitOfWork is a static class -- you can't mock it with RhinoMocks.

UnitOfWork.Current is a public static property, so you can swap it out. Unfortunately, the setter is internal.

I see 3 options for you:

  • Modify the Rhino.Commons source to make UnitOfWork.Current setter public, and set it in your unit test.

  • Use reflection to set the UnitOfWork.Current to your fake unit of work.

  • Since UnitOfWork.Current internally uses Local.Data to find the current transaction, you should be able to go:

    Rhino.Commons.Local.Data[UnitOfWork.CurrentUnitOfWorkKey] = myFakeUnitOfWork;

One bit of good news is that UnitOfWork.Current is an IUnitOfWork, and RhinoMocks can easily fake interfaces.

I must finish by saying, I'm not very familiar with Rhino.Commons, so Ayende might have built a proper way of faking UnitOfWork. If this is super-important to you, you ought to ask in the Rhino discussion groups.

Judah Himango
A: 

Thanks, but I've actually decided to ignore mocking of the Rhino infrastructure. I found this post by Ayende http://ayende.com/Blog/archive/2009/04/28/nhibernate-unit-testing.aspx on using a sqlite database rebuilt with every test. This has been a great solution!

Mateusz Kubiczek
+1  A: 

I had a similar need, because I wanted to test the logic around the persistence without actually testing the persistence of the data. I found I could mock/stub the UnitOfWork easily using these 2 lines in the SetUp portion of my tests:

IUnitOfWork theStubUnitOfWork = MockRepository.GenerateStub<IUnitOfWork>();
UnitOfWork.RegisterGlobalUnitOfWork(theStubUnitOfWork);
Ogre Psalm33