Most developers that use unit testing in their applications probably know what a mocking library is. In case you don’t, a mocking library provides a way to mock a portion of your code, allowing your application to work as is without having to write any special code to do so.
Most mocking libraries on the web require the use of interfaces; this is because an interface makes it easier to switch the actual implementation from a live object to a mocked one. The interface defines the signature and thus makes it easy to ensure the mocked object also implements the same interface. This design implementation has a minimal impact regarding to the amount of coding effort, but has a bigger impact on the design of the application.
TypeMock works around some of the issues by supplying a very dynamic mocking library that does not require the use of interfaces. Actually, any object, whether implementing an interface or not, can be mocked, which gives TypeMock a lot of power.
TypeMock originally provided two different ways to write tests. One of those approaches was to use the MockManager class. The MockManager class has a static
Mock method that returned a Mock object that you could define your mocks with. The following could be a mock for a class defined using the MockManager.
Listing 1: Using the MockManager Class
TypeMock uses this class to define the series of properties and method calls that will occur in this specific test case, and then validate the results.
The second approach uses natural mocking: a more natural approach to reading and reacting to code called in a unit test. This flowing style of running test code worked really well and felt more natural to the tester, because the developer actually writes the code as in:
Listing 2: Using the RecorderManager class
The challenge with this way to develop unit tests is that the natural way can’t be used with internal/private methods. This is rectified using the MockManager approach, but then that’s a mix and match of the two options, which isn’t wrong or hard to do, but it would be nice if one solution solved both issues.
TypeMock now brings forth some new objects to develop unit tests with: the ArrangeActAssert namespace. The idea of the Arrange/Act/Assert process is a way to develop unit tests. It starts by arranging the test and all associated mocks, followed by the setting up of the code to actually perform the work of the test, and lastly the assertion process verifies that all outputs are correct.
To bring these objects into your testing framework, import the C# and VB.NET API’s referenced in the latest TypeMock assembly. Let’s begin by looking at a basic mock:
Listing 3: Mocking MyClass in TypeMock
In Listing 3, the new Arrange/Act/Assert approach divides the test up into three parts. The arrange part uses the new TypeMock instance/static methods to setup the objects to mock, along with its properties and methods to call or mock. The second part, the act part, sets up the class and gets the value. The third part, the assertion part, verifies that the class is correct.
Let’s walk through the arrange portion of the test. The Isolate object, a static object, is the core object to defining mockings. Its Fake property returns an object that allows a developer to mock an instance or static class/method. It’s generic to specify the class to mock, but to mock a static object, use the overload which accepts the type of an object.
SwapNextInstance method swaps the next creation of the class with the mock. Later on, when MyClass is instantiated, the object returned is swapped with the mock object, something handy to have. The other method,
WhenCalled, is another very useful method that allows us to control what actually gets called or mocked. When the
Value property is called on the MyClass mock instance, a value of
1 is returned.
So you can see
WhenCalled is important because it controls the actions of your code, and can control the inner workings of code. Using the
WillReturn method ignores the call to the code defined within
() notation is a lambda expression that allows you to specify code segments to run, and the code within
WhenCalled gets controlled by the following method option. Using
CallOriginal() will call the original method implementation.
When it comes to
WhenCalled, this method can be used to test not only properties as shown above, but also methods (as I also stated), along with the setters of a property. If the above code segment was rewritten to set the
Value property to another value, this would serve to mock the setter of that property, instead of the getter of the property as defined above.
Alternatively, TypeMock provides the ability to mock private properties/methods, using the
NonPublic property of the Isolate object. While not as fully featured as public members, private members use the MockManager definition-like approach to setup what needs mocked, and what action should take. This could be done using the following:
Listing 4: Working with Non-Public Members
NonPublic object’s members require a fake object. This means that you have to have a fake specified using the
NonPublic can also fake static members, by using an override that takes a Type object instead.
TypeMock, using this new approach, can mock static objects too. For instance, if you have code that uses the factory method pattern, TypeMock can mock the static method using the Isolate object. The following code segments could be used to mock that static create method:
Listing 5: Setting Up Mocking For Factory Pattern
In this way, the static method can be mocked to do whatever you need to. Typically, the a faked instance of the type being created could be returned by changing
TypeMock provides one other feature I’ll mention in this article: verification. The
Isolate.Verify property returns an object that is used to perform verification that the correct object’s properties or methods are called during the code’s execution. It can be used to verify that either a public or private method was called, with or without argument checking.
For instance, at the end of a test, the code below could be used to determine that a public method was called, and a private property had its setter called:
Listing 6: Verifying that the Correct Methods were Called
The first method verifies that
obj.SetValue was called with the exact parameter argument of
WasCalledWithAnyArguments was used instead, the parameter wouldn’t matter. The second call checks that the
Value property, a private property, was called to assign this value.
Verification can also work the other way; it can check to see that a method wasn’t called, which can also be useful.
TypeMock is cool, and you can see that you do not need to use an interface to mock an object; it can work with any object directly through the use of generics. TypeMock can mock anything through a new Isolate keyword; using the Fake member to create the actual fake, and the
WhenCalled method to change the internals to the code calling and actually change the behavior. The
NonPublic member can also manipulate private methods too.
This development approach is a hybrid of the two approaches I mentioned at the beginning of the article, to create a new way to develop unit tests in a more managed way.
Brian Mains is an application developer consultant with Computer Aid Inc. He formerly worked with the Department of Public Welfare.
In both places of business, he developed both windows and web applications, small and large, using the latest .NET technologies. In addition, he had spent many hou...
This author has published 73 articles on DotNetSlackers. View other articles or the complete profile here.
You might also be interested in the following related blog posts
Using T4MVC strongly-typed helpers with Telerik Extensions for ASP.NET MVC
Silverlight 3 Activity control
Custom Panels in Silverlight/WPF Part 3: Animation
Pie Chart Easy AS.
Custom Panels in Silverlight/WPF: Introduction
Custom Panels in Silverlight/WPF Part 2: ArrangeOverride
How to use Ninject 2 with ASP.NET MVC
The ASP.NET MVC ActionController The controllerless action, or actionless controller
IActiveScriptParse and x64
Going Controller-less in MVC: The Way Fowler Meant It To Be
Please login to rate or to leave a comment.