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.
Returning new MockObject in the delegate method is allowed only with the Enterprise License.
All code that is run inside the delegate is not mocked.
Copyright © Typemock Ltd. 2004-2008. All Rights Reserved.