7

I am trying to do Test Driven Development as a single developer (possibly increasing the team to four). I have experience using NUnit to a limited extend for unit testing.

I have been developing this system for a couple of years (VB.NET). The developer before me was working on the system for three years and he favored Martin Fowlers Transaction Script approach meaning that there are large classes with large monolithic functions with virtually no consideration about design/re useability etc.

I have looked into some of the Mocking frameworks available for Nunit and I believe the only option I have is the commercial product TypeMock (RhinoMock vs. TypeMock vs. NUnit's Mocking?) as it allows you to mock classes that are none abstract and without interfaces. Is this correct?

I have read some posts on here that suggest this is not the case. Hence the reason for this question. Can I use any free mocking frameworks for Transaction script/monolithic systems?

Community
  • 1
  • 1
w0051977
  • 15,099
  • 32
  • 152
  • 329

1 Answers1

25

Short Answer

If you don't have an abstract class, or an interface, then you will have to use product like TypeMock or Microsoft's Fakes.

Long Answer

Don't go down this route. The chief virtue of TDD is that it forces you to have loosely coupled code, and clear abstractions. Without that, then your tests will become ridiculously hard to setup, and maintain.

What you really need to do is to refactor. Slowly. Here is my recommendation.

  1. Start by finding a component that is hard to test, and identify all your dependencies.
  2. Start extracting interfaces from those classes, and then make the dependent class depend on the interfaces instead.
  3. Invert the dependencies by making them "injectable" via the constructor or a property.
  4. Start writing tests to describe the behavior of that class, mocking the dependencies.
  5. Rinse repeat until you can begin to tame your code base.

Mocking classes without interfaces can be useful for code that you don't control. But it is still hard, and will get unwieldy and complicated over time.

Let your tests talk to you. If your tests are difficult to work with, or complicated to setup, then it means your code needs to be refactored. Don't ignore that feedback.

Josh
  • 44,706
  • 7
  • 102
  • 124
  • 2
    +1 I'd always advocate following a path that will lead to small, loosely coupled units - and once you have that then there's plenty of free Mocking frameworks out there - [Moq](https://code.google.com/p/moq/) being my personal favourite. – Mike Jul 06 '13 at 13:25
  • +1 for Moq. I was a Rhino Mocks guy for a very long time, but have been exclusively using Moq for years now. – Josh Jul 06 '13 at 13:27
  • Thanks for the clear answer +1. I am refactoring the code as I go along. Therefore part of the app is now transaction script (monolithic) and part is domain model (abstractions, interfaces, polymorphism etc). Is it common for an app to be in this state during refactoring? Should I use mock objects for the refactored code only? – w0051977 Jul 06 '13 at 15:37
  • @w0051977 - Any legacy application that wasn't built from the ground up with TDD will probably look like this. Honestly, I would focus my Unit Testing efforts on code I could control/mock, and use Integration tests for the areas that I couldn't. That way you at least have *some* testing coverage when you start to refactor. – Josh Jul 06 '13 at 16:02