Search code examples
c#unit-testingasp.net-coremoqxunit

How to verify log message in Unit testing for a passing test?


I'm testing an endpoint. I need to figure out how to get the test to pass with my loggerMock. Here is how I currently have the test set up:

public void GetExceptionReportSessionData_Returns200OK()
        {
            //Arrange 
            var response = new RetrieveExceptionReportSessionDatesResponse
            {
                RetrieveExceptionReportSessionDatesResult = string.Empty
            };
            var serviceClient = new Mock<WorkflowService.WorkflowService>();      
            serviceClient
                .Setup(x => x.RetrieveExceptionReportSessionDatesAsync(It.IsAny<RetrieveExceptionReportSessionDatesRequest>()))
               .ReturnsAsync(response);

            var loggerMock = new Mock<ILogger>();
            loggerMock.Setup(x => x.LogInfo(null));

            var controller = new ExceptionReportController(loggerMock.Object);

            var ctx = new ControllerContext() { HttpContext = new DefaultHttpContext() };
            ctx.HttpContext.Request.Headers["token"] = "fake_token_here"; //Set header
            controller.ControllerContext = ctx;

            //Act
            var result = controller.GetExceptionReportSessionData();

            //Assert
            var viewResult = Assert.IsType<OkObjectResult>(result);
            Assert.Equal(StatusCodes.Status200OK, viewResult.StatusCode);


        }

Here is how the logger is setup in the endpoint when returning a 200:

if (result != null && result.ExceptionReportLines != null && result.ExceptionReportLines.Count > 0)
            {
                logText = LogFormatter.Format(
                                WebUtilities.GetUser((ClaimsIdentity)HttpContext.User.Identity),
                                startTime, DateTime.Now, Privilege.ViewOrderExceptionReport,
                                "Get Exception Report", "Exception Report retrieved successfully.");
                logger.LogInfo(logText);
            }
            else
            {
                logText = LogFormatter.Format
                                (WebUtilities.GetUser((ClaimsIdentity)HttpContext.User.Identity),
                                startTime, DateTime.Now, Privilege.ViewOrderExceptionReport,
                                "Get Exception Report", "Exception report is empty for the given report filters.");
                logger.LogWarn(logText);
            }

            return Ok(result);

My test is set up so that the latter message appears. How can I get the test to pass?


Solution

  • Instead of passing just a null value to Setup of LogInfo method you can use an expression to match the logText string

    loggerMock
        .Setup(x => x.LogInfo(It.Is<string>(s => s.Contains("Exception Report retrieved successfully."))))
        .Verifiable();
    

    And use Verify() in Assert step

    loggerMock.Verify();
    

    It ensures, that LogInfo() method in loggerMock was called with string matches the specified expression. Have a look at matching arguments in Moq wiki for more details