This section takes you through some of the basics of Typemock Isolator
Faking Objects
- Behaviors
- Verifying Behaviors
Don’t forget that to use Typemock Isolator, you need to reference TypeMock.dll and Typemock.ArrangeActAssert.Dll.
Faking Objects
Creating Fake Objects
Fake objects replace real objects in the test. We create fake objects to isolate objects that represent an external dependency in your test. Their behavior is set up using Isolate.WhenCalled() and verified using Isolate.Verify.
To create a fake object, use the Isolate.Fake.Instance<T>() method:
RealLogger fake = Isolate.Fake.Instance<RealLogger>();
Fake objects can be created with a few predefined behaviors, that set the fake object’s default behavior. You define the behavior types by passing a Members enum parameter to Isolate.Fake.Instance<T>(). The possible behavior types are:
- Members.ReturnRecursiveFake: The fake object will return zero or equivalent to any call on methods returning value types, and return fake objects for any methods returning a reference type. The returned fake objects will behave in the same way.
- Members.MustSpecifyReturnValues: Before using methods that return a value on the fake object, their behavior must be defined.
- Members.CallOriginal: The fake object will pass through any calls made on it to their original implementation.
- Members.ReturnNulls: The fake object will return zero or equivalent to any call on methods returning value types, and null for any methods returning a reference type. Void calls are ignored.
Members.ReturnRecursiveFake is the default fake object behavior. This means that calling Isolate.Fake.Instance<T>() is the same as passing in Members.ReturnRecursiveFake.
Members.ReturnRecursiveFake behavior is a powerful faking tool, automatically faking chained calls even several levels down the object model. No need to explicitly fake return values and behavior for each hierarchy level.
In this example, the fake RealLogger we create calls GetSon() which in turn returns another a Son object on which another call is made:
public void RecursiveStubWithExpectationOnSecondLevel () |
RealLogger fake = Isolate.Fake.Instance<RealLogger>(Members.ReturnRecursiveFake); |
Isolate.WhenCalled(() => fake.GetSon().DoSomething()).WillReturn(10); |
Logger son = fake.GetSon(); |
Isolate.Verify.WasCalledWithAnyArguments(() => fake.GetSon().DoSomething()); |
Future Instances
Sometimes we want fake the runtime behavior for objects instantiated in the code under test, also known as ‘Future instance’. We set up the objects as shown above, to be swapped with the future object at the time of its creation. This is done using the Isolate.Swap.NextInstance<T>().With<T>() method.
public void FutureInstance_VerifyMethodWasCalledAndStubbed () |
RealLogger fake = Isolate.Fake.Instance<RealLogger>(); |
/ replace a future instance of RealLogger with the fake object we created |
Isolate.Swap.NextInstance<RealLogger>().With(fake); |
/ set up additional fake object behavior |
Isolate.WhenCalled(() => fake.Increment()).IgnoreCall(); |
Controlling Behavior
Method Behavior
When you create fake objects, all method calls are handled according to its default behavior, specified on creation. You can set specific method’s behavior by using Isolate.WhenCalled():
RealLogger fake = Isolate.Fake.Instance<RealLogger>(); |
Isolate.WhenCalled(() => fake.Increment()).CallOriginal(); |
Isolate.WhenCalled() sets up completing statements that specify the desired method behavior, such as:
Isolate.WhenCalled(() => fake.ReturnInt()).WillReturn(10); / this is fine |
Isolate.WhenCalled(() => fake.ReturnInt()).WillReturn( "ten" );/ this will not compile |
Static methods are called on class types, not on fake instances, so there is no creation involved when setting up behavior for fake static method. Instead, we use Isolate.Fake.StaticMethods():
Isolate.Fake.StaticMethods(); |
Static classes cannot be passed as type arguments to StaticMethods(), so an overload is provided to pass them as type parameters:
Isolate.Fake.StaticMethods( typeof (StaticClassToFake)); |
For example, here’s how you test static methods:
public void TestStaticMethods() |
/ define static method faking behavior for LoggerFactory |
Isolate.Fake.StaticMethods(Members.CallOriginal); |
/ define specific faking behavior for a chained call starting with static call |
Isolate.WhenCalled(() => LoggerFactory.GetLogger().GetSon().DoSomething()).WillReturn(10); |
Assert.AreEqual(10, LoggerFactory.GetLogger().GetSon().DoSomething()); |
/ Verify a static call was made |
Isolate.Verify.WasCalledWithAnyArgumnets(() => LoggerFactory.GetLogger().GetSon()); |
Faking Behavior for Live Objects
A live object is a test object which has been instantiated normally, not through Isolator. When you only want to modify an object’s behavior for a specific method call, just fake the specific behavior using Isolate.Fake.Instance<T>():
RealLogger logger = new RealLogger(); / this is a normal "live" object |
Isolate.WhenCalled(() => logger.Log( "message" )).IgnoreCall(); / ignore only the Log method |
As you can see, we set the return value of MethodReturnInt to 10 only when the arguments are 3 and “abc”, and set the return value of MethodReturnInt to 50 only when the arguments are 3 and “xyz”.
Verifying Behaviors
When writing unit tests, you may want to make sure that specific calls were made or correct parameters were passed into function calls. This is easily done with Isolate.Verify with a completing verification statement.
- WasCalledWithAnyArguments() – Verifies the call was made at least once during the test execution
- WasCalledWithExactArguments() – Verifies the call was made at least once during the test execution with the provided arguments
- WasNotCalled() – Verifies the call wan’t called during the test execution
- WasCalledWithArguments() – Verifies the call was made at least once with arguments matching a predicate
Verification is performed on fake objects and goes over the information collected during the test execution for them.