Chained Natural Mocks™

Chained calls are multiple calls, where each method is called on the returned object of the former method. For example:
ProductFactory.GetProduct("dummy").CalculatePrice(1) - The static method GetProduct returns an instance that the method CalculatePrice is called on.

In the example above, if we used Reflective Mocks,  we would need to first create a mock for the Product instance returned by GetProduct, and then set on that instance the expectation of the CalculatePrice Method. However, using Natural Mocks™  makes testing chaining calls much easier. With this feature we can use this simple syntax:

Example - Chained Call
Hide C# Code
Hide Visual Basic Code
// C#
public void ChainedCodeExample ()
{
    // ...
    bool ok = MyDatabaseFactory.GetDatabase().Insert(name);
    // ...
}

' Visual Basic
Public Sub ChainedCodeExample ()
   ' ...
   Dim ok As Boolean = MyDatabaseFactory.GetDatabase().Insert(name)
   ' ...
End Sub
Example - Using Natural Mocks™ For Setting Expectations on Chains

Let's test the ChainedCodeExample method when Insert  returns false.

// C#
[Test] public void Authenticated ()
{
     using (RecordExpectations recorder = RecorderManager.StartRecording())
     {
        // CAUTION: ALL calls here are mocked!!!
        recorder.ExpectAndReturn(MyDatabaseFactory.GetDatabase().Insert(""),false);
     }
     // Thats it folks
     // ...
}

' Visual Basic
<Test()> Public Sub Authenticated ()
    ' For .NET 2.0 (see .NET 1.1 Syntax here )
    Using recorder As New RecordExpectations
       ' CAUTION: ALL calls here are mocked!!!
       recorder.ExpectAndReturn(MyDatabaseFactory.GetDatabase().Insert(""),False)
    End Using
    ' Thats it folks
    ' ...  
End Sub

As we are not checking arguments, we passed an empty string to the insert method.

All RecordExpectations methods (Return, Throw, Unmocked) apply only to the LAST method of the chain.

Conditional Expectations apply only to the LAST method of the chain.

Repeat and RepeatAlways apply to the ENTIRE chain.

To change these to the entire chain, use the following:

When using default CheckArguments and Conditional Expectations the CheckArguments method applies to ALL the methods in the chain, and requires an item for each argument of all methods passed.

Care should be taken when using recorder.DefaultBehavior.WhenArgumentsMatch; see Conditional Expectations for further explanations.


Copyright © Typemock Ltd. 2004-2010. All Rights Reserved.