Kyl*_* L. 4 c# unit-testing moq xunit .net-core
为了在 .NET Core 3 中正确测试自定义 ExceptionFilterAttribute,我们需要使用 Moq 在 Xunit 测试中模拟 ExceptionContext。我怎样才能做到这一点?
异常过滤器:
public class CustomExceptionFilter : ExceptionFilterAttribute
{
public override OnException(ExceptionContext context)
{
/* Code here that handles exceptions */
}
}
Run Code Online (Sandbox Code Playgroud)
我到处都找过了,但找不到一种好方法来模拟这些东西,以确保不会因其他缺失的依赖项而引发异常。我怎样才能ExceptionContext轻松嘲笑?
问题在于,如果您尝试模拟ExceptionContext以返回不同的异常类型,那么您实际上想要模拟异常,然后在实例化ExceptionContext.
首先,要ExceptionContext在测试中实例化 for 过滤器,您需要能够实例化ActionContext. 这ActionContext与我们的测试无关,但依赖关系树需要它,因此我们必须以尽可能少的定制来实例化它:
var actionContext = new ActionContext()
{
HttpContext = new DefaultHttpContext(),
RouteData = new RouteData(),
ActionDescriptor = new ActionDescriptor()
};
Run Code Online (Sandbox Code Playgroud)
在能够实例化之后,ActionContext您可以实例化 ExceptionContext。在这里,我们还模拟了用于构建ExceptionContext. 这是最重要的一步,因为这是改变我们正在测试的行为的值。
// The stacktrace message and source member variables are virtual and so we can stub them here.
var mockException = new Mock<Exception>();
mockException.Setup(e => e.StackTrace)
.Returns("Test stacktrace");
mockException.Setup(e => e.Message)
.Returns("Test message");
mockException.Setup(e => e.Source)
.Returns("Test source");
var exceptionContext = new ExceptionContext(actionContext, new List<FilterMetadata>())
{
Exception = mockException.Object
};
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以在给定不同异常类型时充分测试异常过滤器的行为。
完整代码:
[Fact]
public void TestExceptionFilter()
{
var actionContext = new ActionContext()
{
HttpContext = new DefaultHttpContext(),
RouteData = new RouteData(),
ActionDescriptor = new ActionDescriptor()
};
// The stacktrace message and source member variables are virtual and so we can stub them here.
var mockException = new Mock<Exception>();
mockException.Setup(e => e.StackTrace)
.Returns("Test stacktrace");
mockException.Setup(e => e.Message)
.Returns("Test message");
mockException.Setup(e => e.Source)
.Returns("Test source");
// the List<FilterMetadata> here doesn't have much relevance in the test but is required
// for instantiation. So we instantiate a new instance of it with no members to ensure
// it does not effect the test.
var exceptionContext = new ExceptionContext(actionContext, new List<FilterMetadata>())
{
Exception = mockException.Object
};
var filter = new CustomExceptionFilter();
filter.OnException(exceptionContext);
// Assumption here that your exception filter modifies status codes.
// Just used as an example of how you can assert in this test.
context.HttpContext.Response.StatusCode.Should().Be(500,
"Because the response code should match the exception thrown.");
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4248 次 |
| 最近记录: |