Mvc: TryValidateModel lève une exception lors du test de l'unité

Créé le 21 mars 2017  ·  3Commentaires  ·  Source: aspnet/Mvc

J'ai ce qui semble être un problème très similaire au numéro 3586, où TryValidateModel lève une erreur de référence d'objet lors du test de l'unité. Pendant le fonctionnement normal avec des données similaires transmises au contrôleur, la validation réussit. Voici la méthode du contrôleur:

    public class LocationsController : Controller
    {
        [HttpPut("{id}")]
        public IActionResult PartiallyUpdateLocation(int id,
            [FromBody] JsonPatchDocument<LocationForUpdateDTO> patchDoc)
        {
            if (patchDoc == null)
            {
                return BadRequest();
            }

            var locationEntity = _locationsRepository.GetLocation(id);
            if (locationEntity == null)
            {
                return NotFound();
            }

            var locationToPatch = Mapper.Map<LocationForUpdateDTO>(locationEntity);

            patchDoc.ApplyTo(locationToPatch, ModelState);

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            **FAILS HERE**
            TryValidateModel(locationToPatch);

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var finalLocation = Mapper.Map(locationToPatch, locationEntity);

            _locationsRepository.PartiallyUpdate(id, finalLocation);
            return NoContent();
        }
    }

... et voici l'implémentation du test unitaire:

    [Collection("AutoMapper collection")]
    public class LocationsController_PatchLocationTests
    {
        AutoMapperConfigFixture fixture;

        public LocationsController_PatchLocationTests(AutoMapperConfigFixture fixture)
        {
            this.fixture = fixture;
        }

        [Fact]
        public void PatchLocationReturnsNoContent()
        {
            var repositoryMock = GetMockRepositoryHelper(1);
            LocationsController controller = new LocationsController(repositoryMock);
            var patchDoc = new JsonPatchDocument<LocationForUpdateDTO>();
            patchDoc.Replace(l => l.Street, TestDataForPartialUpdate.goodLocation.Street);
            Mapper.Initialize(cfg =>
            {
                cfg.CreateMap<Location, LocationForUpdateDTO>();
            });

            var result = controller.PartiallyUpdateLocation(1, patchDoc);

            Assert.IsType(typeof(NoContentResult), result);
        }

        private static ILocationsRepository GetMockRepositoryHelper(int id)
        {
            Mock<ILocationsRepository> repositoryMock = new Mock<ILocationsRepository>();
            repositoryMock.Setup(x => x.GetLocation(id))
                .Returns(
                    new Location()
                    {
                        Id = 1,
                        Street = "123 AppleTree Way",
                        City = "Galloway",
                        State = "Ohio",
                        ZipCode = "43119",
                        Latitude = 40.0,
                        Longitude = 80.0
                    });

            return repositoryMock.Object;
        }
    }

Ainsi que l'Automapper CollectionDefinition:

    [CollectionDefinition("AutoMapper collection")]
    public class AutoMapperConfig : ICollectionFixture<AutoMapperConfigFixture>
    {

    }

La trace de pile:

à Microsoft.AspNetCore.Mvc.ControllerBase.TryValidateModel (modèle d'objet, préfixe de chaîne)
à LocationsAPI.Controllers.LocationsController.PartiallyUpdateLocation (ID Int32, JsonPatchDocument`1 patchDoc) dans le chemin édité \ src \ LocationsAPI \ Controllers \ LocationsController.cs: ligne 138
à LocationsAPI.Tests.Unit.LocationsController_PatchLocationTests.PatchLocationReturnsNoContent () dans le chemin édité \ test \ LocationsAPI.Tests.Unit \ LocationsController_PatchLocationTests.cs: ligne 36

question

Commentaire le plus utile

@rynowak J'avais juste le même problème. tandis que la recherche de réponse me débarque sur cette page. même l'ajout du code ci-dessous résout le problème. Mais il ne semble pas juste que nous devions le faire pour utiliser TryValidateModel pour les tests unitaires.

et ces connaissances (ou informations) ne sont pas mentionnées dans le document de ControllerBase.TryValidateModel

Cela ne semble pas correct car ce morceau de code ne fait partie d'aucune de notre logique de test. Si nous ne pouvons pas améliorer cela, nous devrions au moins le mentionner dans la documentation de TryValidateModel.

var objectValidator = new Mock<IObjectModelValidator>(); objectValidator.Setup(o => o.Validate(It.IsAny<ActionContext>(), It.IsAny<ValidationStateDictionary>(), It.IsAny<string>(), It.IsAny<Object>())); _sut.ObjectValidator = objectValidator.Object;

Tous les 3 commentaires

Vous devrez définir controller.ObjectValidator lorsque vous essayez de tester tout ce qui appelle TryValidateModel . Je me demande si nous pouvons faire quelque chose pour améliorer les choses.

Clôture parce que cela semble être répondu. Si cela ne résout pas le problème, veuillez réactiver ou ouvrir un nouveau problème

@rynowak J'avais juste le même problème. tandis que la recherche de réponse me débarque sur cette page. même l'ajout du code ci-dessous résout le problème. Mais il ne semble pas juste que nous devions le faire pour utiliser TryValidateModel pour les tests unitaires.

et ces connaissances (ou informations) ne sont pas mentionnées dans le document de ControllerBase.TryValidateModel

Cela ne semble pas correct car ce morceau de code ne fait partie d'aucune de notre logique de test. Si nous ne pouvons pas améliorer cela, nous devrions au moins le mentionner dans la documentation de TryValidateModel.

var objectValidator = new Mock<IObjectModelValidator>(); objectValidator.Setup(o => o.Validate(It.IsAny<ActionContext>(), It.IsAny<ValidationStateDictionary>(), It.IsAny<string>(), It.IsAny<Object>())); _sut.ObjectValidator = objectValidator.Object;

Cette page vous a été utile?
0 / 5 - 0 notes