Using Moq 4.18.1 to test my C# code, I'm wanting to verify a method calls another method. In the class being tested I have this:
public class IntegratedPlatformRepository : PvRepository<OutputDTO>, IIntegratedPlatformRepository
{
protected virtual async Task IpSpecificGetterExtras(OutputDTO dto, CancellationToken cancellationToken) { }
public async Task<OutputDTO> GetAsync(Guid uid, CancellationToken cancellationToken = default) {
var dto = ...
await IpSpecificGetterExtras(dto, cancellationToken);
...
}
I want to ensure that IpSpecificGetterExtras
is called when GetAsync
is called, so I tried this:
[Fact]
public async Task GetAsync_Calls_IpSpecificGetterExtras()
{
// Arrange
var mock = new Mock<IntegratedPlatformRepository> {
CallBase = true
};
// Act
await _repo.GetAsync(Guid.NewGuid().ToString());
// Assert
mock
.Protected()
.Verify<Task>(
"IpSpecificGetterExtras", Times.Once(),
ItExpr.IsAny<OutputDTO>(), ItExpr.IsAny<CancellationToken>()
);
}
If I simply run the test it fails saying the invocation wasn't performed. If I debug the test and set a breakpoint in IpSpecificGetterExtras
the breakpoint is hit and I can step through the method, so it's definitely being called.
CodePudding user response:
Based on the shown example mock
was not invoked.
The test needs to be refactored to allow it to flow to completion so that it can be verified as expected.
[Fact]
public async Task GetAsync_Calls_IpSpecificGetterExtras() {
// Arrange
var mock = new Mock<IntegratedPlatformRepository> {
CallBase = true
};
mock.Protected()
.Setup<Task>("IpSpecificGetterExtras",
ItExpr.IsAny<OutputDTO>(), ItExpr.IsAny<CancellationToken>())
.Returns(Task.CompletedTask);
var subject = mock.Object;
// Act
await subject.GetAsync(Guid.NewGuid().ToString());
// Assert
mock
.Protected()
.Verify<Task>(
"IpSpecificGetterExtras", Times.Once(),
ItExpr.IsAny<OutputDTO>(), ItExpr.IsAny<CancellationToken>()
);
}