Create the test project
The first step is to create a new Visual Studio 2010 Visual C# class library project and call it TypeMockDemo.Fixture and add the following references to it:
The references are pointing to:
- my TDD framework nUnit (you can work with any TDD framework but I personally found nUnit to be the best out there )
- TypeMock assemblies, installed in the GAC of your machine
- The TypeMockDemo project (the one we have the domain entities in)
Now we can start to create the first class fixture and verify that we can create a new Person, a new Employee and a new Customer. But hold on a second! How can we mock an abstract and two sealed class with a mocking framework? We simply cant if we are not using TypeMock
Looking at the code we have introduced the new method Isolate.Fake.Instance<T> that is coming from TypeMock. With this method we can simply inform TypeMock that we want it will create for us a Proxy of the object we want to mock and it will return a derived class of the tested one, even if we are mocking a sealed class.
If the class is sealed TypeMock will create a new instance of the original object while if the object is abstract, TypeMock will create a proxy version of that object. Same thing will be done for all the child properties, complex or not
Thats simply wow, we just used two lines of code to create a mockup and test it.
Now lets move forward and lets verify that we will not be able to add the same address twice and to remove the same address twice from a Person object.
Working with Instances or Proxy?
First of all we start to create this simple test but the result is not the one we expect
nUnit bombs saying that at line 8 the expected result is supposed to be 1 but in reality is 0. Why? This happens because TypeMock has created a full mockup proxy of the person object so also the methods AddAddress and RemoveAddress are mocks and they do not point to the real code we have implemented
If we change the way TypeMock is creating the object Person, we can now say to it:
Dear TypeMock, I want that you create an instance of my object and that you call its constructor so that I can test the code I have implemented in this abstract class
Et voila, the test will pass! Same thing for the remove address and so on
Now, the last test we may require is that we want to be sure that when we create a new address, the constructor is properly injecting the parent Person object so that we can keep a back-forward reference from the parent object and the collection of children.
We run the test and kabum! It fails again. This time it fails on the address side because the Person instance TypeMock is injecting is not the same it returned to use in the previous line of code. So what can we do now?
We can manually create an Address and inject the parent Person but it sucks or we can do this:
We simply inject the person value we want to use (the one created by TypeMock) because this is what it is going to happen with live code. What we care here is to be sure that inside the Address class constructor, the Person parameter is passed to the read-only property Person of the Address class, nothing more, nothing less!