Sealed mocking is one of the advanced features supported in Telerik JustMock.
It allows you to fake sealed classes and calls to their methods/properties, set expectations and verify results using the AAA principle.
Faking sealed classes and calls to their methods/properties doesn't affect the way you write your tests, i.e. the same syntax is used
for mocking non sealed classes.
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 and interface to test:
CopyC#
public sealed class FooSealed
{
public int Echo(int arg1)
{
return arg1;
}
}
public sealed class FooSealedInternal
{
internal FooSealedInternal()
{
}
public int Echo(int arg1)
{
return arg1;
}
}
CopyVB
Public NotInheritable Class FooSealed
Public Function Echo(arg1 As Integer) As Integer
Return arg1
End Function
End Class
Public NotInheritable Class FooSealedInternal
Friend Sub New()
End Sub
Public Function Echo(arg1 As Integer) As Integer
Return arg1
End Function
End Class
CopyC#
public interface IFoo
{
void Execute();
void Execute(int arg1);
}
public sealed class Foo : IFoo
{
public void Execute()
{
throw new NotImplementedException();
}
void IFoo.Execute(int arg1)
{
throw new NotImplementedException();
}
}
CopyVB
Public Interface IFoo
Sub Execute()
Sub Execute(arg1 As Integer)
End Interface
Public NotInheritable Class Foo
Implements IFoo
Public Sub Execute() Implements IFoo.Execute
Throw New NotImplementedException()
End Sub
Private Sub Execute(arg1 As Integer) Implements IFoo.Execute
Throw New NotImplementedException()
End Sub
End Class
Assert Final Method Call on a Sealed Class
Set up a call to a final method on a sealed class and assert its return value.
CopyC#
[TestMethod]
public void ShouldAssertFinalMethodCallOnASealedClass()
{
var foo = Mock.Create<FooSealed>();
Mock.Arrange(() => foo.Echo(Arg.IsAny<int>())).Returns(10);
var actual = foo.Echo(1);
Assert.AreEqual(10, actual);
}
CopyVB
<TestMethod()>
Public Sub ShouldAssertFinalMethodCallOnASealedClass()
Dim foo = Mock.Create(Of FooSealed)()
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.
Create Mock for Sealed Class with Internal Constructor
Even the sealed class has only an internal constructor we can still
create a mock, call its methods and verify the results.
CopyC#
[TestMethod]
public void ShouldCreateMockForASealedClassWithInternalConstructor()
{
var foo = Mock.Create<FooSealedInternal>();
Mock.Arrange(() => foo.Echo(Arg.IsAny<int>())).Returns(10);
Assert.IsNotNull(foo);
var actual = foo.Echo(1);
Assert.AreEqual(10, actual);
}
CopyVB
<TestMethod()>
Public Sub ShouldCreateMockForASealedClassWithInternalConstructor()
Dim foo = Mock.Create(Of FooSealedInternal)()
Mock.Arrange(Function() foo.Echo(Arg.IsAny(Of Integer)())).Returns(10)
Assert.IsNotNull(foo)
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. After we ensure that the object is actually created, we assert for the return value of the foo.Echo method.
Create Mock for Sealed Class with Interface
When a mock is created by using Mock.Create all dependencies are also implemented.
In the example below we mock the Foo class, which implements the IFoo interface.
CopyC#
[TestMethod]
public void ShouldAssertCallOnVoid()
{
var foo = Mock.Create<Foo>();
bool called = false;
Mock.Arrange(() => foo.Execute()).DoInstead(() => called = true);
foo.Execute();
Assert.IsTrue(called);
}
CopyVB
<TestMethod()>
Public Sub ShouldAssertCallOnVoid()
Dim foo = Mock.Create(Of Foo)()
Dim called As Boolean = False
Mock.Arrange(Sub() foo.Execute()).DoInstead(Sub() called = True)
foo.Execute()
Assert.IsTrue(called)
End Sub
Furthermore, if you are interested in IFoo interface implementation you can use the
as operator and call the interface members as shown below.
CopyC#
[TestMethod]
public void ShouldAssertCallOnVoidThroughAnInterface()
{
var foo = Mock.Create<Foo>();
bool called = false;
Mock.Arrange(() => foo.Execute()).DoInstead(() => called = true);
IFoo iFoo = foo;
iFoo.Execute();
Assert.IsTrue(called);
}
CopyVB
<TestMethod()>
Public Sub ShouldAssertCallOnVoidThroughAnInterface()
Dim foo = Mock.Create(Of Foo)()
Dim called As Boolean = False
Mock.Arrange(Sub() foo.Execute()).DoInstead(Sub() called = True)
Dim iFoo As IFoo = foo
iFoo.Execute()
Assert.IsTrue(called)
End SubIn both examples a local variable is set to true once the Execute method is called.
See Also