Final mocking is one of the advanced features supported in Telerik JustMock.
It allows you to fake final method/property calls, set expectations and verify results using the AAA principle.
Faking final or virtual method/property calls doesn't affect the way you write your tests, i.e. the same syntax is used
for mocking both final and non-final calls.
Note |
|---|
This feature is available only in the commercial version of Telerik JustMock. Refer to this topic to learn more about the differences between both the commercial and free versions of Telerik JustMock. |
In the further examples we will use the following sample classes to test:
CopyC#
public class Foo
{
public int Execute(int arg1, int arg2)
{
throw new NotImplementedException();
}
public int Execute(int arg1)
{
throw new NotImplementedException();
}
public int Echo(int arg1)
{
return arg1;
}
public string FooProp { get; set; }
public delegate void EchoEventHandler(bool echoed);
public event EchoEventHandler OnEchoCallback;
}
public class FooGeneric
{
public TRet Echo<T, TRet>(T arg1)
{
throw new NotImplementedException();
}
}
CopyVB
Public Class Foo
Public Function Execute(arg1 As Integer, arg2 As Integer) As Integer
Throw New NotImplementedException()
End Function
Public Function Execute(arg1 As Integer) As Integer
Throw New NotImplementedException()
End Function
Public Function Echo(arg1 As Integer) As Integer
Return arg1
End Function
Public Property FooProp() As String
Get
Return m_FooProp
End Get
Set(value As String)
m_FooProp = value
End Set
End Property
Private m_FooProp As String
Public Delegate Sub EchoEventHandler(echoed As Boolean)
Public Event OnEchoCallback As EchoEventHandler
End Class
Public Class FooGeneric
Public Function Echo(Of T, TRet)(arg1 As T) As TRet
Throw New NotImplementedException()
End Function
End Class
Assert Final Method Setup
Set up a call to a final method and assert its return value.
CopyC#
[TestMethod]
public void ShouldSetupACallToAFinalMethod()
{
var foo = Mock.Create<Foo>();
Mock.Arrange(() => foo.Echo(Arg.IsAny<int>())).Returns(10);
var actual = foo.Echo(1);
Assert.AreEqual(10, actual);
}
CopyVB
<TestMethod()>
Public Sub ShouldSetupACallToAFinalMethod()
Dim foo = Mock.Create(Of Foo)()
Mock.Arrange(Function() foo.Echo(Arg.IsAny(Of Integer)())).Returns(10)
Dim actual = foo.Echo(1)
Assert.AreEqual(10, actual)
End Sub
Here we setup that a call to the final foo.Echo method with any int argument
should return 10.
Follows the same example in F#:
| F# | Copy |
|---|
[<Test()>]
member this.ShouldMockFinalMember() =
let foo = Mock.Create<Foo>()
Mock.Arrange(foo, fun foo -> foo.Echo(Arg.AnyInt)).Returns(10);
let ret = foo.Echo(1)
Assert.AreEqual(10, ret)
|
Assert Property Get
Set up a call to a final property and assert its return value.
CopyC#
[TestMethod]
public void ShouldSetupACallToAFinalProperty()
{
var foo = Mock.Create<Foo>();
Mock.Arrange(() => foo.FooProp).Returns("bar");
var actual = string.Empty;
actual = foo.FooProp;
Assert.AreEqual("bar", actual);
}
CopyVB
<TestMethod()>
Public Sub ShouldSetupACallToAFinalProperty()
Dim foo = Mock.Create(Of Foo)()
Mock.Arrange(Function() foo.FooProp).Returns("bar")
Dim actual = String.Empty
actual = foo.FooProp
Assert.AreEqual("bar", actual)
End Sub
Here we setup that a call to the final foo.FooProp property should return the "bar" literal.
Assert Property Set
In this example we arrange the FooProp property of the Foo class.
CopyC#
[TestMethod]
[ExpectedException(typeof(MockException))]
public void ShouldAssertPropertySet()
{
var foo = Mock.Create<Foo>(Behavior.Strict);
Mock.ArrangeSet(() => foo.FooProp = "ping");
foo.FooProp = "foo";
}
CopyVB
<TestMethod()>
<ExpectedException(GetType(MockException))>
Public Sub ShouldAssertPropertySet()
Dim foo = Mock.Create(Of Foo)(Behavior.Strict)
Mock.ArrangeSet(Function() foo.FooProp = "ping")
foo.FooProp = "foo"
End Sub
Here we setup that setting the final foo.FooProp property to any string value
different from "ping" will cause an exception of type MockException to be thrown.
Assert Method Overloads
This example shows how to mock final method overloads.
foo.Execute has two overloads - accepting one or two integers as arguments.
Here we mock them both by Returns. In the first case we return just the argument that has been passed.
In the second case we return the sum of the two integer values.
After that, we act by calling both overloads and assert what we have arranged.
CopyC#
[TestMethod]
public void ShouldAssertOnMethodOverload()
{
var foo = Mock.Create<Foo>();
Mock.Arrange(() => foo.Execute(Arg.IsAny<int>())).Returns((int result) => result);
Mock.Arrange(() => foo.Execute(Arg.IsAny<int>(), Arg.IsAny<int>())).Returns((int arg1, int arg2) => arg1 + arg2);
Assert.AreEqual(foo.Execute(1), 1);
Assert.AreEqual(foo.Execute(1, 1), 2);
}
CopyVB
<TestMethod()>
Public Sub ShouldAssertOnMethodOverload()
Dim foo = Mock.Create(Of Foo)()
Mock.Arrange(Function() foo.Execute(Arg.IsAny(Of Integer)())).Returns(Function(result As Integer) result)
Mock.Arrange(Function() foo.Execute(Arg.IsAny(Of Integer)(), Arg.IsAny(Of Integer)())).Returns(Function(arg1 As Integer, arg2 As Integer) arg1 + arg2)
Assert.AreEqual(foo.Execute(1), 1)
Assert.AreEqual(foo.Execute(1, 1), 2)
End Sub
Assert Method Callbacks
Follows an example of how to use the Raises method to fire a callback
and pass event arguments once a final method is called.
CopyC#
[TestMethod]
public void ShouldAssertOnMethodCallbacks()
{
var foo = Mock.Create<Foo>();
Mock.Arrange(() => foo.Echo(Arg.IsAny<int>())).Raises(() => foo.OnEchoCallback += null, true);
bool called = false;
foo.OnEchoCallback += delegate(bool echoed)
{
called = echoed;
};
foo.Echo(10);
Assert.IsTrue(called);
}
CopyVB
<TestMethod()>
Public Sub ShouldAssertOnMethodCallbacks()
Dim foo = Mock.Create(Of Foo)()
Mock.Arrange(Function() foo.Echo(Arg.IsAny(Of Integer)())).Raises(Sub() AddHandler foo.OnEchoCallback, Nothing, True)
Dim called As Boolean = False
AddHandler foo.OnEchoCallback, Sub(echoed As Boolean)called = echoed
foo.Echo(10)
Assert.IsTrue(called)
End SubWhen the foo.Echo() method is called with any integer value as argument
the OnEchoCallback is raised with parameter true. We attach a delegate to
the event to set a local boolean variable to true once the method is called.
We act by calling foo.Echo(10).
Finally, we verify that foo.Echo() has been called in our test.
Assert Generic Types and Methods
You can also assert generic types and methods. In the example below we mock generic method
in non-generic type. We arrange that it should return the string value that has been passed to it.
CopyC#
[TestMethod]
public void ShouldAssertOnGenericTypesAndMethod()
{
string expected = "ping";
var foo = Mock.Create<FooGeneric>();
Mock.Arrange(() => foo.Echo<string, string>(expected)).Returns((string s) => s);
string ret = foo.Echo<string, string>(expected);
Assert.AreEqual(expected, ret);
}
CopyVB
<TestMethod()>
Public Sub ShouldAssertOnGenericTypesAndMethod()
Dim expected As String = "ping"
Dim foo = Mock.Create(Of FooGeneric)()
Mock.Arrange(Function() foo.Echo(Of String, String)(expected)).Returns(Function(s As String) s)
Dim ret As String = foo.Echo(Of String, String)(expected)
Assert.AreEqual(expected, ret)
End SubFor more information about mocking generic types and methods go to Generics topic.
See Also
Other Resources
[d0e29c40-c54c-4994-a030-38855ba89cc6]