I have a unit test class method that currently takes 1 parameter but I want to extend it to receive 2 parameters with the latter being the number of times invocation is met on a mock object. What I currently have is something like this, which doesn't compile successfully due to errors
[Theory]
[InlineData("", Times.Never)]
[InlineData("test", Times.Once)]
public async void PostAsync_SendAsync_VerifyOnce(string id, Times outcome)
{
var mockClients = new Mock<IHubClients>();
...
...
...
mockClients.Verify(clients => clients.Client(id), outcome);
}
Is it possible to achieve something like this? So in theory both tests here should pass, the first will never be invocated as the first parameter is blank and the second test will be invocated once as the parameter is valid.
CodePudding user response:
You can achieve this using the Times.Exactly
method:
[Theory]
[InlineData("", 0)]
[InlineData("test", 1)]
public async void PostAsync_SendAsync_VerifyOnce(string id, int expectedCalls)
{
var mockClients = new Mock<IHubClients>();
...
...
...
mockClients.Verify(clients => clients.Client(id), Times.Exactly(expectedCalls));
}
CodePudding user response:
Use a TheoryData
and bind it to your test via a MemberDataAttribute
, that allows to make those Times.Once()
and Times.Never()
method calls.
It also allows other scenarios like AtLeast
and AtMost
.
public static TheoryData GetTestCases()
{
return new TheoryData<string, Times>()
{
{ "", Times.Never() },
{ "test", Times.Once() }
};
}
[Theory]
[MemberData(nameof(GetTestCases))]
public void PostAsyncSendAsyncVerifyOnce(string id, Times outcome)
{
var mockClients = new Mock<IHubClients>();
// ...
mockClients.Verify(clients => clients.Client(id), outcome);
}