如何使用MOQ正确测试我的控制器方法?

问题描述

我正在制作一个动物收容所Web应用程序,员工可以在该应用程序上将动物添加数据库中。可以将动物放置在某些庇护所中。这些避难所的容量最大。

我正在编写的第一个测试是检查是否已达到所选住宅的最大容量时ModelState无效的测试。但是,我似乎无法弄清楚如何使用XUnit和MOQ对此进行正确的测试。

我的AnimalController类的属性和构造函数

public class AnimalController : Controller
    {
        private readonly IAnimalRepository _animalRepository;
        private readonly IResidenceRepository _residenceRepository;
        private readonly IAnimalShelterService _animalShelterService;

        public AnimalController(IAnimalRepository animalRepository,IResidenceRepository residenceRepository,IAnimalShelterService animalShelterService)
        {
            _animalRepository = animalRepository;
            _residenceRepository = residenceRepository;
            _animalShelterService = animalShelterService;
        }

同一控制器中的NewAnimal方法

        [HttpPost]
        [ValidateAntiForgeryToken]
        public async Task<IActionResult> NewAnimal(NewAnimalviewmodel newAnimal)
        {
            // Retrieve the selected residence and set this to the animal's residence.
            var selectedResidence = _residenceRepository.GetById(newAnimal.ResidenceId);
            newAnimal.Residence = selectedResidence;

            try
            {
                Animal animalToCreate = new Animal()
                {
                    Name = newAnimal.Name,Birthdate = newAnimal.Birthdate,EstimatedAge = newAnimal.EstimatedAge,Age = newAnimal.Age,Description = newAnimal.Description,Type = newAnimal.Type,Breed = newAnimal.Breed,Gender = newAnimal.Gender,Photo = newAnimal.Photo,ArrivalDate = newAnimal.ArrivalDate,SterilizedOrCastrated = newAnimal.SterilizedOrCastrated,ChildFriendly = newAnimal.ChildFriendly,Reason = newAnimal.Reason,Adoptable = newAnimal.Adoptable,Residence = newAnimal.Residence,ResidenceId = newAnimal.ResidenceId
                };

                _animalShelterService.CheckCapacity(animalToCreate,selectedResidence);
                _animalShelterService.CheckCompatibleTypes(animalToCreate,selectedResidence);
                _animalShelterService.CheckSterilizedOrCastratedAnimals(animalToCreate,selectedResidence);

                if (ModelState.IsValid)
                {

                    await _animalRepository.AddAnimal(animalToCreate);

                    return RedirectToAction("Index");
                }
            }
            catch (Exception e)
            {
                ModelState.AddModelError(nameof(newAnimal.Birthdate),e.Message);
            }

            PrefillSelectOptions();

            return View(newAnimal);
        }

AnimalShelterService类中的CheckCapacity方法

public void CheckCapacity(Animal animaltocheck,Residence residencetocheck)
        {
            // Retrieve the amount of animals in the selected residence and the max capacity of this residence.
            var animalCount = _animalRepository.GetCountByResidence(animaltocheck.ResidenceId);
            var maxCapacity = residencetocheck.MaxCapacity;

            // Throw an exception if the current amount of animals in the residence is equal to its max capacity.
            if (animalCount == maxCapacity)
            {
                throw new InvalidOperationException(
                    "The selected residence is currently full. Please select another residence.");
            }
        }

我编写的测试(可能根本没有意义):

[Fact]
        public async Task NewAnimal_Exceeds_Residence_MaxCapacity_Should_Return_ModelError()
        {
            // Arrange
            var animalRepoMock = new Mock<IAnimalRepository>();
            var residenceRepoMock = new Mock<IResidenceRepository>();
            var animalShelterServiceMock = new Mock<IAnimalShelterService>();
        
            var sut = new AnimalController(animalRepoMock.Object,residenceRepoMock.Object,animalShelterServiceMock.Object);

            residenceRepoMock.Setup(residenceRepo => residenceRepo.GetById(1)).Returns(new Residence()
            {
                Id = 1,Name = "INDIV_DOGS_TEST_001",AnimalType = AnimalType.Dog,ResidenceType = ResidenceType.Individual,MaxCapacity = 1
            });

            Animal animalX = new Animal()
            {
                Name = "Samson",Birthdate = new DateTime(2018,01,01),Age = 2,Description = "Bark",Type = AnimalType.Dog,Gender = Gender.Male,ArrivalDate = new DateTime(2020,10,SterilizedOrCastrated = true,Reason = "Needs a new home.",Adoptable = true,ResidenceId = 1
            };

            animalRepoMock.Setup(animalRepo => animalRepo.GetById(1)).Returns(animalX);

            // Act
            NewAnimalviewmodel animalY = new NewAnimalviewmodel()
            {
                Name = "Fikkie",Birthdate = new DateTime(2017,Age = 3,Description = "Woof",03),ChildFriendly = true,ResidenceId = 1
            };
        
            var result = await sut.NewAnimal(animalY);
        
            // Assert
            var viewResult = result as ViewResult;
        
            Assert.False(viewResult.ViewData.ModelState.IsValid);
        }

我只是不知道我应该在嘲笑什么,以及如何使它工作。当前,它返回一个NullReferenceException。任何帮助将不胜感激,因为我在互联网上找不到太多帮助。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)