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.
The example uses reflective Typemock mocks but can also be used with Natural Mocks™ using Return or ExpectAndReturn.
Example - Dynamic Return Values
// 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.
Returning MockManager.CONTINUE_WITH_METHOD will tell Typemock Isolator to continue with the normal method code. See Unmocked Expectations for more information.
All code that is run inside the delegate is not mocked.
Copyright © Typemock Ltd. 2004-2010. All Rights Reserved.