TypeMock tutorial #02. Object creation.

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 can’t if we are not using TypeMock … 

Create new abstract and Sealed
  1. [Test]
  2. [Category(“Domain.Isolated”)]
  3. public void AssertThatCanCreateANewPerson()
  4. {
  5.     Person person = Isolate.Fake.Instance<Person>();
  6.     Assert.That(person, Is.Not.Null);
  7. }
  8. [Test]
  9. [Category(“Domain.Isolated”)]
  10. public void AssertThatCanCreateANewEmployee()
  11. {
  12.     Person person = Isolate.Fake.Instance<Employee>();
  13.     Assert.That(person, Is.Not.Null);
  14. }
  15. [Test]
  16. [Category(“Domain.Isolated”)]
  17. public void AssertThatCanCreateANewCustomer()
  18. {
  19.     Person person = Isolate.Fake.Instance<Customer>();
  20.     Assert.That(person, Is.Not.Null);
  21. }

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 …

 

That’s simply wow, we just used two lines of code to create a mockup and test it.

Now let’s move forward and let’s 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 …

Test a collection
  1. [Test]
  2. [Category(“Domain.Isolated”)]
  3. public void AssertThatCanAddTheSameAddressTwice()
  4. {
  5.     Person person = Isolate.Fake.Instance<Person>();
  6.     Address address = Isolate.Fake.Instance<Address>();
  7.     person.AddAddress(address);
  8.     Assert.That(person.Addresses.Count(), Is.EqualTo(1));
  9.     Assert.Throws<InvalidOperationException>(() => person.AddAddress(address));
  10. }

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 …

Control the creation
  1. [Test]
  2. [Category(“Domain.Isolated”)]
  3. public void AssertThatCanAddTheSameAddressTwice()
  4. {
  5.     Person person = Isolate.Fake.Instance<Person>(Members.CallOriginal, ConstructorWillBe.Called);
  6.     Address address = Isolate.Fake.Instance<Address>();
  7.     person.AddAddress(address);
  8.     Assert.That(person.Addresses.Count(), Is.EqualTo(1));
  9.     Assert.Throws<InvalidOperationException>(() => person.AddAddress(address));
  10. }

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.

Test injection in constructor
  1. [Test]
  2. [Category(“Domain.Isolated”)]
  3. public void AssertThatWhenCreateAnAddressTheParentPersonIsInjected()
  4. {
  5.     Person person = Isolate.Fake.Instance<Person>(Members.CallOriginal, ConstructorWillBe.Called);
  6.     Address address = Isolate.Fake.Instance<Address>();
  7.     Assert.That(person, Is.Not.Null);
  8.     Assert.That(address, Is.Not.Null);
  9.     Assert.That(address, Has.Property(“Person”).EqualTo(person));
  10. }

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:

Customize constructor
  1. [Test]
  2. [Category(“Domain.Isolated”)]
  3. public void AssertThatWhenCreateAnAddressTheParentPersonIsInjected()
  4. {
  5.     Person person = Isolate.Fake.Instance<Person>(Members.CallOriginal, ConstructorWillBe.Called);
  6.     Address address = Isolate.Fake.Instance<Address>(Members.CallOriginal, ConstructorWillBe.Called, person);
  7.     Assert.That(person, Is.Not.Null);
  8.     Assert.That(address, Is.Not.Null);
  9.     Assert.That(address, Has.Property(“Person”).EqualTo(person));
  10. }

 

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!

Leave a comment

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