Wednesday, June 28, 2006 - Posts

Checking for mocked parameters in Natural Mock expectations

TypeMock nicely introduced the Check.IsMock functionality with their 3.1.4 release and this ties in very nicely with the Natural Mock stuff they've introduced in their soon to be released 3.5.0.

e.g. we have a production method which uses a singleton's CommandManager object to ExecuteCommand using a new InitialisationCommand but we want to mock the whole call including the new InitialisationCommand:

public void Foo()

{

   this.initialised = UIPManager.Instance.CommandManager.ExecuteCommand(new InitialisationCommand());

}

So code up a testcase as follows:

[Test]

public void FooTest_RecorderManager()

{

   Mock mockInitialisationCommand = MockManager.Mock(typeof (InitialisationCommand), Constructor.Mocked); //(1)

   using (RecordExpectations recordExpectations = RecorderManager.StartRecording()) //(2)

   {

      recordExpectations.ExpectAndReturn(UIPManager.Instance.CommandManager.ExecuteCommand(null), false);

      recordExpectations.CheckArguments(Check.IsMock(mockInitialisationCommand)); //(3)

   }

   this.vFrameworkEntryPoint.Foo();

   Assert.IsFalse(this.vFrameworkEntryPoint.Initialised);

}

(1) We create a mock to handle the creation of the new InitialisationCommand

(2) Using a Natural Mock we configure it to expected a call to 'UIPManager.Instance.CommandManager.ExecuteCommand' and return false.

(3) We configure the Natural Mock to check that the argument provided in the ExpectAndReturn we just configured is the mock of the new InitialisationCommand.

//NB// You will also notice that we are now using the object model directly within the test (UIPManager. and so on) so our tests automatically become more resilient to refactoring work - if, for example, the ExecuteCommand is renamed or the signature altered the solution will fail to compile until the tests have been updated. Big Bonus! (If you use a tool like Resharper then you could have it renamed for you)

TypeMock.Net 3.5.0 Preview

TypeMock.Net have been kind enough to send me a pre-release of their latest release at v3.5.0.

There are several new features including improved support for usage within the Visual Studio .Net 2005 IDE but the new toy that I can say interests me the most with this new release is Natural TypeMock (TM).

I have been struggling recently with a solution which started life as a test driven project but the project ran into difficulties and the approach was discarded for a while - however, it is now desirable for them to resurrect and apply unit testing to their solution (see my previous rant). The problem occurs with the prolific use of static contructors on loggers and other such objects some of which are singletons to boot. To date I have been forced to construct elaborate mocking objects to be able to mock these calls - this has entailed the usual method of setting expectations using a string to match the method/getter etc - this is where Natural TypeMock comes into its own.

With Natural TypeMocks you can code up the unit test using the context sensitive help of the ide (sweet!) so the compile will fail if you refactor the production classes without adjusting the mocks - nice, heh!

The magic happens using RecordExpectations on the RecordManager:

using (RecordExpectations recorder = RecorderManager.StartRecording())
{
    Logger.Log(Logger.NORMAL,null);
    Logger.Log(Logger.NORMAL,null);
}

You set the expectations within the block by recording the actions you're expecting during the test run - very tidy.

The arguments are checked if they are non-null values so to check for specific arguments to the logging functions:

using (RecordExpectations recorder = RecorderManager.StartRecording())
{
    Logger.Log(Logger.NORMAL,"First expected log message");
    Logger.Log(Logger.NORMAL,"Second expected log message");
    recorder.CheckArguments();
}



To check arguments and return an expected value is just as simple:

using (RecordExpectations recorder = RecorderManager.StartRecording())
{
    recorder.ExpectAndReturn(Logger.Log(Logger.NORMAL,"First expected log message"), false);
}



I will be pitting the new features of TypeMock against the solution tomorrow so will follow up with any problems/solutions that I encounter along the way!

Keep an eye out for it at TypeMock website.