Unit Testing A Concrete Template

Batch Job Layout
Batch Job Layout

Spent some time today putting unit tests around some changes I was making to a class that runs a batch routine.  The batch routine is implemented as a class that  inherits from a base abstract batch class.  The base class provides methods for all the pieces parts for running a batch job including an abstract method, ‘ExecuteLogic’, that the concrete implementation is to implement to actually do it’s work.

I’m not sure this is such a good setup, basically the ‘RunJob’ method is implemented in the base class and calls the other base methods in a templated order.  It doesn’t call every method,  ‘SetLoggingMessage’  is a base class method that is often called in concrete implementations of the ‘ExecuteLogic’ method.  Something is weird here, but right now I’m only concerned with testing my changes.  Perhaps I’ll look at a little refactoring later.

Generally I’m looking to test the ‘ExecuteLogic’ method implemented in the concrete batch job.  However, some of the concrete batch jobs have calls in their ‘ExecuteLogic’ routine that call base class methods that write to logs or to a database.  There isn’t an easy way to replace the objects in the base class routines that write to the database and the log with mocks, which makes isolating the ‘ExecuteLogic’ method difficult.   Someone suggesting mocking the base class, essentially mocking the instance itself under test, and having the ‘ExecuteLogic’ method take as a parameter it’s own type and pass itself, allowing us to mock it.  We all agreed this was a bad idea, I thought there would be risk of unintended recursion, others thought it wouldn’t make sense to others looking at the code.

What we came up with was having a class we could mock that would take a delegate and then execute that delegate.  When running the ‘ExecuteLogic’ method we’d use the real delegate invoking class, and when testing pass in a mock so we could confirm the proper calls were being made against the delegate invoker.  This seemed a whole lot better then having a class mock itself, and seemed to achieve the desired goal, being able to account for the base class calls while testing the ‘ExecuteLogic’ method, without having to actually have them run.  Still not sure if this is a good solution or not, perhaps we’ll come up with a better one tomorrow.

Also, it’s not clear if the ‘ExecuteLogic’ method should be public, it’s in an exe so perhaps it doesn’t matter, but it’s public so it can be tested.  I’m not so sure if a method should be public just to be testable, but I’m willing to live with it in this case.

Leave a Reply

Your email address will not be published. Required fields are marked *