aspnet / Mvc

[Archived] ASP.NET Core MVC is a model view controller framework for building dynamic web sites with clean separation of concerns, including the merged MVC, Web API, and Web Pages w/ Razor. Project moved to https://github.com/aspnet/AspNetCore

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unit Test with TryUpdateModelAsync fails with argument null exception Parameter name: metadataProvider

rrjamesjr opened this issue · comments

Is this a Bug or Feature request?:

Bug

Steps to reproduce (preferably a link to a GitHub repo with a repro project):

`
[HttpPatch("{id}")]
[ProducesResponseType(typeof(IDictionary<string, string>), (int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.NotFound)]
[ProducesResponseType((int)HttpStatusCode.NoContent)]
[ProducesResponseType((int)HttpStatusCode.InternalServerError)]
[Consumes(Constants.JsonPatch)]

    public async Task<IActionResult> Patch(int id, [FromBody, Required] JsonPatchDocument<MyDto> myDto)
    {
        try
        {
            var  original = new MyDto();
            myDto.ApplyTo(original);
            
            if(!await TryUpdateModelAsync<MyDto>(original))
            {
                return BadRequest(ModelState);
            }                
        }
        catch (Exception e)
        {
            logger.LogError(e, string.Empty);
            return StatusCode((int)HttpStatusCode.InternalServerError, e);
        }

        return NoContent();
    }`

Description of the problem:

The above code executes fine but when manual testing but my unit test method fails with argument null exception Parameter name: metadataProvider when calling TryUpdateModelAsync method.

Version of Microsoft.AspNetCore.Mvc or Microsoft.AspNetCore.App or Microsoft.AspNetCore.All:

Microsoft.AspNetCore.App version 2.1.1

commented

@rrjamesjr, please share with us the project so we can repro the unit-test failure.

commented

@rrjamesjr, looks like you haven't properly configured the ValueProviderFactories of the ControllerContext for the controller being tested:
image

The ControllerBase.TryUpdateModelAsync method delegates the work to

public static async Task<bool> TryUpdateModelAsync(

which in turn requires the modelMetadataProvider to be available.

@pranavkm, do we have a sample which would showcase how to do this properly?

If you'd like to unit test your controller action, I'd go the route of stubbing ControllerBase.TryUpdateModelAsync to verify if it does the right thing. If you're looking for an integration style test where the framework method executes as is, https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.1 has pretty detailed documentation on how you'd set this up.

Thanks...just mocked the controller and stubbed the method as suggested