单元测试自定义 InputFormatter

Unit test custom InputFormatter

我已经从 添加了自定义 InputFormatter,但想为 class 添加单元测试。

有没有简单的方法来做到这一点? 我正在查看 ReadRequestBodyAsyncInputFormatterContext 参数,它似乎很复杂,需要构建它的许多其他对象,而且看起来很难模拟。 有人能做到吗?

我在 .Net5 上使用 xUnit 和 Moq

代码

public class RawJsonBodyInputFormatter : InputFormatter
{
    public RawJsonBodyInputFormatter()
    {
        this.SupportedMediaTypes.Add("application/json");
    }

    public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
    {
        var request = context.HttpContext.Request;
        using (var reader = new StreamReader(request.Body))
        {
            var content = await reader.ReadToEndAsync();
            return await InputFormatterResult.SuccessAsync(content);
        }
    }

    protected override bool CanReadType(Type type)
    {
        return type == typeof(string);
    }
}

我只创建了一个 ControllerContext 用于模拟,它还必须实例化一个 HttpContext:

controllerBase.ControllerContext = new ControllerContext
{
    HttpContext = new DefaultHttpContext
    {
        RequestServices = new ServiceCollection()
            .AddOptions()
            .AddAuthenticationCore(options =>
            {
                options.DefaultScheme = MyAuthHandler.SchemeName;
                options.AddScheme(MyAuthHandler.SchemeName, s => s.HandlerType = typeof(MyAuthHandler));
            }).BuildServiceProvider()
    }
};

要模拟您案例中的其他属性,您可以查看 BodyModelBinderTests.cs,如果有什么可以使用的话。

我找到了 InputFormatter 的 aspnetcore 测试并从 here:

获得了这段代码
context = new InputFormatterContext(
                new DefaultHttpContext(),
                "something",
                new ModelStateDictionary(),
                new EmptyModelMetadataProvider().GetMetadataForType(typeof(object)),
                (stream, encoding) => new StreamReader(stream, encoding));

我还从 JsonInputFormatterTestBase

那里得到了一些其他有用的提示