Modifying The Method Logic
You can modify the implementation of a mocked method, and when the method is called it will run the custom logic that you had entered.
When to Use
When you need to change the mocked method logic.
Syntax
C# Isolate.WhenCalled(() => fake.<method>).DoInstead{()=> //your custom logic };
VB
Isolate.WhenCalled(Function() fake.<method>).DoInstead(Function()
//your custom logic
)
How to Use
To run a custom logic in a faked method, use DoInstead after WhenCalled and provide your own delegate. DoInstead passes MethodCallContext with the following members:
Member |
Description |
Instance |
An instance of the calling object (null if the method is static) |
Parameters |
Array of objects of the arguments passed to the method (if exist) |
Method |
A MethodBase object that contains method metadata that can be used for choosing the required behavior |
ContinueFakingThisMethodRecursively |
Boolean flag to enable and disable recursively faking method |
WillCallOriginal() |
Calls the original implementation |
Samples
Sample 1:
The following sample shows the following:
•DoInstead sends a custom delegate that will run when GetID is called.
• The actual call to GetID will call the custom delegate.
Overloads for DoInstead also exist for void methods and non-public methods.
C# // Note: Use Isolated to clean up after the test [TestMethod, Isolated] public void DoInstead_Example() { var returnValue = 2; var fakeDependency = Isolate.Fake.Instance<Dependency>(); // return value dynamically Isolate.WhenCalled(() => fakeDependency.GetID()).DoInstead( x => { return returnValue; }); returnValue = 4; var result = new ClassUnderTest().AddToDependency(1, fakeDependency); Assert.AreEqual(5, result); } public int AddToDependency(int a, Dependency dependency) { return a + dependency.GetID(); }
VB
' Note: Use Isolated to clean up after the test
<TestMethod(), Isolated()>
Public Sub DoInstead_Example()
Dim returnValue = 2
Dim fakeDependency = Isolate.Fake.Instance(Of Dependency)()
' return value dynamically
Isolate.WhenCalled(Function() fakeDependency.GetID()).DoInstead(Function(x)
Return returnValue
End Function)
returnValue = 4
Dim result = New ClassUnderTest().AddToDependency(1, fakeDependency)
Assert.AreEqual(5, result)
End Sub
Public Function AddToDependency(a As Integer, dependency As Dependency) As Integer
Return a + dependency.GetID()
End Function
Sample 2: Running Custom Logic and Continuing with the Original Method
The following example shows how to apply a custom logic and then continue with the implementation of the original method.
C# [TestMethod, Isolated] public void WhenCalledDoInstead_RunOriginalAfterLogic() { var fakeDependency = new Dependency(); int counter = 0; Isolate.WhenCalled(() => fakeDependency.Calculate()).DoInstead( c => { // Custom logic before original call counter++; // Make sure the method gets called immediately after leaving c.WillCallOriginal(); return null; }); fakeDependency.Calculate(); Assert.IsTrue(counter == 1); }
VB
<TestMethod(), Isolated()>
Public Sub WhenCalledDoInstead_RunOriginalAfterLogic()
Dim fakeDependency = New Dependency()
Dim counter As Integer = 0
Isolate.WhenCalled(Function() fakeDependency.Calculate())
.DoInstead(Function(c)
' Custom logic before original call
counter += 1
' Make sure the method gets called immediately after leaving
c.WillCallOriginal()
Return Nothing
End Function)
fakeDependency.Calculate()
Assert.IsTrue(counter = 1)
End Sub
Sample 3: Calling the Original Method but with another arguments
The following example shows how to change an argument and then continue with the implementation of the original method.
If it's possible, Typemock makes an implicit conversion of an arguments.
C# public class Dependency { public int Increment(int i) { return i + 1; } } [TestMethod, Isolated] public void WhenCalledDoInstead_RunOriginalAfterLogic() { var fakeDependency = new Dependency(); Isolate.WhenCalled(() => fakeDependency.Increment(0)).DoInstead( c => { // Changing argument before original call c.Parameters[0] = 100; // Make sure the method gets called immediately after leaving c.WillCallOriginal(); return null; }); var res = fakeDependency.Increment(1); Assert.IsTrue(res == 101); }
VB
Public Class Dependency
Public Function Increment(i As Integer) As Integer
Return i + 1
End Sub
End Class
<TestMethod(), Isolated()>
Public Sub WhenCalledDoInstead_RunOriginalAfterLogic()
Dim fakeDependency = New Dependency()
Isolate.WhenCalled(Function() fakeDependency.Increment(0))
.DoInstead(Function(c)
' Changing argument before original call
c.Parameters(0) = 100
' Make sure the method gets called immediately after leaving
c.WillCallOriginal()
Return Nothing
End Function)
Dim res = fakeDependency.Increment(1)
Assert.IsTrue(res = 101)
End Sub
Sample 4: Running Custom Logic in Recursion
The following example shows how to use ContinueFakingThisMethodRecursivly flag.
By default, with the first hit of DoInstead() block faking for beahavior is done. To create more complex, recursion-based logic for DoInstead(), you need to enable it be setting ContinueFakingThisMethodRecursivly flag to true.
C# public class Dependency { public void DoStuff(int i) { throw new NotImplementedException(); } } public class ClassForRecursion { public int count = 0; private Dependency dependency; public ClassForRecursion(Dependency dependency) { this.dependency = dependency; } public void Foo(int i) { count++; if (i < 5) { dependency.DoStuff(i); } } } [TestMethod, Isolated] public void DoInstead_WithRecursion() { var dependency = new Dependency(); var classForRecursion = new ClassForRecursion(dependency); Isolate.WhenCalled(() => dependency.DoStuff(0)).DoInstead( context => { int passedVal = (int) context.Parameters[0]; context.ContinueFakingThisMethodRecursively = true; classForRecursion.Foo(passedVal + 1); } ); classForRecursion.Foo(1); Assert.AreEqual(5, classForRecursion.count); }
VB
Public Class Dependency
Public Sub DoStuff(i As Integer)
Throw New NotImplementedException()
End Sub
End Class
Public Class ClassForRecursion
Public count As Integer = 0
Private dependency As Dependency
Public Sub New(dependency As Dependency)
Me.dependency = dependency
End Sub
Public Sub Foo(i As Integer)
count += 1
If i < 5 Then
dependency.DoStuff(i)
End If
End Sub
End Class
<TestMethod(), Isolated()>
Public Sub DoInstead_WithRecursion()
Dim dependency = New Dependency()
Dim classForRecursion = New ClassForRecursion(dependency)
Isolate.WhenCalled(Sub() dependency.DoStuff(0)).
DoInstead(Sub(context)
Dim passedVal As Integer = CInt(context.Parameters(0))
context.ContinueFakingThisMethodRecursively = True
classForRecursion.Foo(passedVal + 1)
End Sub)
classForRecursion.Foo(1)
Assert.AreEqual(5, classForRecursion.count)
End Sub