Dynamic Return Values

It is possible to return dynamic values according to the parameters received; this is done by passing a DynamicReturnValue delegate as a return value. This is a very strong feature and can actually mock return values at runtime. Just remember to make sure that you are not rewriting your code as a mock type.

In the following example, we will return the invocation number (i.e., the number of times that the method has been called) for each consecutive call. This is not a real test case but an example of how to use the API.

Tip: The example uses reflective Typemock mocks but can also be used with Natural Mocks™ using Return or ExpectAndReturn.

Example - Dynamic Return Values
Hide C# Code
Hide Visual Basic Code
// C#
// A Class that will return the number of invocations

// We will use a static counter and ignore the parameters
class
MyDynamicReturn
{
   static int counter = 0;
   public object ReturnValue(object[] parameters, object context)
   {
     return counter++;
   }
}

[Test]
public void DynamicReturnValues()

   // Create our invocation counter instance
   MyDynamicReturn dyna = new MyDynamicReturn();
   // Mock our class
   Mock mock = MockManager.Mock(typeof(TestedClass));
   // We are always going to return our dynamic invocation counter
   mock.AlwaysReturn("getInt",new DynamicReturnValue(dyna.ReturnValue));
   // First time returns 0, second 1, third 2 so this test will pass
   TestedClass t = new TestedClass();
   Assert.AreEqual(0,t.getInt());
   Assert.AreEqual(1,t.getInt());
   Assert.AreEqual(2,t.getInt());
   MockManager.Verify();
}

' Visual Basic
' A Class that will return the number of invocations
' We will use a static counter and ignore the parameters

Public Class
MyDynamicReturn
   Shared
counter As Integer = 0
   Public Function ReturnValue(ByVal parameters() As Object, ByVal context As Object) As Object
     counter = counter + 1
     ReturnValue = counter
   End function
End Class

<Test()> Public Sub DynamicReturnValues ()
   ' Create our invocation counter instance
   Dim dyna As MyDynamicReturn = new MyDynamicReturn
   ' Mock our class
   Dim mock As Mock = MockManager.Mock(GetType(TestedClass)) 
   ' We are always going to return our dynamic invocation counter
   mock.AlwaysReturn("getInt",new DynamicReturnValue(AddressOf dyna.ReturnValue))
   ' First time returns 0, second 1, third 2 so this test will pass
   Dim t As TestedClass = new TestedClass
   Assert.AreEqual(0,t.getInt())
   Assert.AreEqual(1,t.getInt())
   Assert.AreEqual(2,t.getInt())
   MockManager.Verify()
End Sub

A good example of this technique is when your code has an Exception handler that displays a dialog box. You do not want any user interaction in your tests as this is very annoying (pressing the OK button for each exception); but you do want to test that an exception is thrown. For example, if the exceptions are created by OurException.CreateException(Exception ex), you can mock it with the following delegation code.

// C#
public object JustThrowTheException(object[] parameters, object context)
{
  throw (Exception)parameters[0];
}

' Visual Basic
Public Function JustThrowTheException(ByVal parameters() As Object, ByVal context As Object) _
    As
Object
  Throw parameters(0)
End Function

As you can see, this is a reference to the object (context is actually the this of the object). This is very powerful as you get a hook to each object and can return values based on that as well. For more information, see the DynamicReturnValue API.

Tip: Returning MockManager.CONTINUE_WITH_METHOD will tell Typemock Isolator to continue with the normal method code. See Unmocked Expectations for more information.

Tip: Returning new MockObject in the delegate method is allowed only with the Enterprise License.

Tip: All code that is run inside the delegate is not mocked.


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