Unit test custom InputFormatter

505 views Asked by At

I have added a custom InputFormatter from https://stackoverflow.com/a/47807117/1093406 but want to add unit testing for the class.

Is there an easy way to do this? I'm looking at the InputFormatterContext parameter to ReadRequestBodyAsync and it seems to be complex with lots of other objects required to construct it and it looks difficult to mock. Has anyone been able to do this?

I'm using xUnit and Moq on .Net5

Code

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);
    }
}
2

There are 2 answers

0
Mog0 On BEST ANSWER

I found the aspnetcore tests for InputFormatter and got this code from here:

context = new InputFormatterContext(
                new DefaultHttpContext(),
                "something",
                new ModelStateDictionary(),
                new EmptyModelMetadataProvider().GetMetadataForType(typeof(object)),
                (stream, encoding) => new StreamReader(stream, encoding));

I also got some other useful hints from JsonInputFormatterTestBase

3
Oliver On

I only created a ControllerContext for mocking and it also has to instantiate a 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()
    }
};

For mocking the other properties in your case, you could take a look at BodyModelBinderTests.cs, if there is something you can use.