JCA*_*JCA 6 c# unit-testing moq xunit asp.net-core
我正在测试一个端点。我需要弄清楚如何让我的 loggerMock 测试通过。以下是我目前设置测试的方式:
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);
}
Run Code Online (Sandbox Code Playgroud)
以下是返回 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);
Run Code Online (Sandbox Code Playgroud)
我的测试已设置为显示后一条消息。我怎样才能通过测试?
Nir*_*edi 17
如果您在 .NET 中使用LogError
、LogDebug
等LogWarning
方法,这些方法就是扩展方法,现在的问题是您无法模拟扩展方法。LogError
因此,您需要做的是模拟当您调用、LogDebug
等方法时实际调用的底层方法LogWarning
。
实际上,所有这些方法都调用Log
方法,因此您需要模拟Log
方法。
方法定义Log
如下
void Log (this ILogger logger, LogLevel logLevel, EventId eventId, Exception exception, string message, params object[] args)
Run Code Online (Sandbox Code Playgroud)
您可以使用扩展方法Log
来模拟方法,LogWarning
如下所示
[Fact]
public void VerifyLogWarning()
{
// Arrange
var loggerMock = new Mock<ILogger<MyClass>>();
var myclass = new MyClass(loggerMock.Object);
// Act
myclass.TestMethod();
// Assert
loggerMock.Verify(
x => x.Log(
It.Is<LogLevel>(l => l == LogLevel.Warning),
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((v, t) => true),
It.IsAny<Exception>(),
It.Is<Func<It.IsAnyType, Exception, string>>((v, t) => true)), Times.Once);
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我们正在验证是否已调用LogWarning
一次作为调用的一部分TestMethod()
。
您还可以验证日志警告消息,如下所示
// Assert
loggerMock.Verify(
x => x.Log(
It.Is<LogLevel>(l => l == LogLevel.Warning),
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((v, t) => v.ToString() == "LogWarning Message......"),
It.IsAny<Exception>(),
It.Is<Func<It.IsAnyType, Exception, string>>((v, t) => true)), Times.Once);
Run Code Online (Sandbox Code Playgroud)
您可以使用表达式来匹配字符串,而不是仅null
向Setup
of方法传递值LogInfo
logText
loggerMock
.Setup(x => x.LogInfo(It.Is<string>(s => s.Contains("Exception Report retrieved successfully."))))
.Verifiable();
Run Code Online (Sandbox Code Playgroud)
Verify()
并在Assert
步骤中使用
loggerMock.Verify();
Run Code Online (Sandbox Code Playgroud)
它确保使用字符串调用的LogInfo()
方法loggerMock
与指定的表达式匹配。查看wiki中的匹配参数Moq
以获取更多详细信息
归档时间: |
|
查看次数: |
17705 次 |
最近记录: |