Must Be Called
The MustBeCalled
method is used to assert that a call to a given method or property is made during the execution of a test.
In this article you will find various examples of the MustBeCalled
usage, for which we will be using the following class:
public class Foo
{
public void Execute()
{
}
public int Execute(int str)
{
return str;
}
public int Echo(int a)
{
return 5;
}
}
Public Class Foo
Public Sub Execute()
End Sub
Public Function Execute(ByVal str As Integer)
Return str
End Function
Public Shared Function Echo(num As Integer) As Integer
Throw New NotImplementedException
End Function
End Class
Assert All Calls Marked as Assertable
Let's arrange that a call must be made and then assert that. Only calls marked as assertable, i.e. with MustBeCalled
, are verified.
[TestMethod]
public void ShouldAssertAllCallsMarkedAsAssertable()
{
// Arrange
var foo = Mock.Create<Foo>();
Mock.Arrange(() => foo.Echo(1)).Returns(1).MustBeCalled();
Mock.Arrange(() => foo.Echo(2)).Returns(2);
// Act
var actual1 = 0;
var actual2 = 0;
actual1 = foo.Echo(1);
actual2 = foo.Echo(2);
// Assert
Assert.AreEqual(1, actual1);
Assert.AreEqual(2, actual2);
Mock.Assert(foo);
}
<TestMethod()>
Public Sub ShouldAssertAllCallsMarkedAsAssertable()
' Arrange
Dim foo = Mock.Create(Of Foo)()
Mock.Arrange(Function() foo.Echo(1)).Returns(1).MustBeCalled()
Mock.Arrange(Function() foo.Echo(2)).Returns(2)
' Act
Dim actual1 = 0
Dim actual2 = 0
actual1 = foo.Echo(1)
actual2 = foo.Echo(2)
' Assert
Assert.AreEqual(1, actual1)
Assert.AreEqual(2, actual2)
Mock.Assert(foo)
End Sub
Here we ensure that foo.Echo
is called with argument 1, however, the call with argument 2 is not verified.
Throwing Exception When MustBeCalled Setup Is Never Invoked
When MustBeCalled
setup for some method is never invoked an exception is thrown. In the following example with foo.Execute()).MustBeCalled();
we specify that foo.Execute
is required to be called but this is never done.
In the next example is used NUnit Testing Framework.
[TestMethod]
public void ShouldThrowExceptionWhenMustBeCalledSetupIsNeverInvoked()
{
// Arrange
var foo = new Foo();
Mock.Arrange(() => foo.Execute()).MustBeCalled();
// Assert
Assert.Throws<AssertFailedException>(() => Mock.Assert(foo));
}
<TestMethod()>
Public Sub ShouldThrowExceptionWhenMustBeCalledSetupIsNeverInvoked()
' Arrange
Dim foo = New Foo()
Mock.Arrange(Sub() foo.Execute()).MustBeCalled()
' Assert
Assert.Throws(Of AssertFailedException)(Sub() Mock.Assert(foo))
End Sub
As a result, when verifying the foo
object, MockAssertion
exception is thrown as foo.Execute
is never actually called.
Using MustBeCalled for Property Set
Let`s assume we have the following interface:
public interface IFoo
{
int Value { get; set; }
}
Public Interface IFoo
Property Value() As Integer
End Interface
You can use MustBeCalled
when arranging property set. Here is an example:
[TestMethod]
public void ShouldArrangeMustBeCalledForPropertySet()
{
// Arrange
var foo = Mock.Create<IFoo>();
Mock.ArrangeSet(() => { foo.Value = 1; })
.DoNothing()
.MustBeCalled();
// Assert
Assert.Throws<AssertFailedException>(() => Mock.Assert(foo));
// Act
foo.Value = 1;
// Assert
Mock.Assert(foo);
}
<TestMethod()>
Public Sub ShouldArrangeMustBeCalledForPropertySet()
' Arrange
Dim foo = Mock.Create(Of IFoo)()
Mock.ArrangeSet(Sub() foo.Value = 1).
DoNothing().
MustBeCalled()
' Assert
Assert.Throws(Of AssertFailedException)(Sub() Mock.Assert(foo))
' Act
foo.Value = 1
' Assert
Mock.Assert(foo)
End Sub
We use DoNothing
to ignore the actual implementation when foo.Value
is set to 1
and specify that it must be set to exactly 1
in our test. Before acting with foo.Value = 1;
an exception of type MockAssertion
would be thrown when asserting foo
. After acting we verify that foo.Value
was previously set to 1
.
Using MustBeCalled When Ignoring Arguments
You can use MustBeCalled
in conjunction with IgnoreArguments
. Here is an example:
[TestMethod]
public void ShouldCombineMustBeCalledWithIgnoreArguments()
{
// Arrange
var foo = Mock.Create<Foo>();
Mock.Arrange(() => foo.Execute(0)).IgnoreArguments().MustBeCalled();
// Act
foo.Execute(10);
// Assert
Mock.Assert(foo);
}
<TestMethod()>
Public Sub ShouldCombineMustBeCalledWithIgnoreArguments()
' Arrange
Dim foo = Mock.Create(Of Foo)()
Mock.Arrange(Function() foo.Execute(0)).IgnoreArguments().MustBeCalled()
' Act
foo.Execute(10)
' Assert
Mock.Assert(foo)
End Sub
We use IgnoreArguments()
to ignore the arguments passed to foo.Execute
method and specify that it must be called. Our acting is by foo.Execute(10);
. Finally, we verify that the method is actually called with some or other argument.