Moq - 尝试测试ActionResult时的空引用异常

时间:2014-12-18 15:41:41

标签: c# unit-testing model-view-controller moq

我正在尝试使用Moq学习单元测试,但我仍然遇到同样的问题。我正在为我的控制器ActionResults编写单元测试,并且我没有创建控制器实例并测试它是否有效的问题。但我有一个ActionResult,它给了我一个空引用异常,因为我在调用控制器之前错过了设置我的测试的东西。

     private PersonController _controller;
     private Mock<ICoreRepository> _repoCore;
     private Mock<IImageRepository> _repoImage;

     [TestInitialize]
     public void Setup()
     {
         _repoCore = new Mock<ICoreRepository>();
         _repoImage = new Mock<IImageRepository>();

         _controller = new PersonController(_repoImage.Object)
         {
             CrmCoreRepository = _repoCore.Object,
             //ImageRepository = _repoImage.Object
         };
      }

        [TestMethod]
        public void UploadImage_NotNull_personImage_Test()
        {

            var controller = new PersonController(_repoImage.Object);
            var model = new GlobalEntityModel
            {
                PersonModel= new PersonModel()
            };

            controller.CrmCoreRepository = _repoCore.Object;
             var uploadedFile = new Mock<HttpPostedFileBase>();

            uploadedFile
                .Setup(f => f.ContentLength)
                .Returns(10);

            uploadedFile
                .Setup(f => f.FileName)
                .Returns("testimage.jpg");

            var imageRepository = new Mock<IImageRepository>();
            imageRepository.Setup(x => x.SaveImage(It.IsAny<HttpPostedFileBase>(), It.IsAny<ImagePaths>()));

            var res = controller.AddOrUpdatePersonDetail(model, uploadedFile.Object);

            Assert.IsNotNull(res);  
        }

在我的测试中,我创建了一个新的控制器实例,模型,一个httppostedfilebase的模拟,我尝试设置图像存储库saveImage。

[HttpPost]
        public ActionResult AddOrUpdatePersonDetail(GlobalEntityModel model, HttpPostedFileBase personImage)
        {
            var uploadedImage = string.Empty;
            var personImagePath = _imageRepository.RetrieveImageFilePath(ImagePaths.PersonImageFilePath);

            if (personImage != null)
            {
                uploadedImage = _imageRepository.SaveImage(personImage, ImagePaths.PersonImageFilePath);
            }

            var personModel = model.PersonModel;
            var personDto = Mapper.MapTo<PersonDto>(personModel);

            //Update Person
            personDto.CreatedBy = "Admin";
            personDto.UpdatedBy = "Admin";
            personDto.UpdatedOn = DateTime.Now;

            if (uploadedImage != string.Empty)
            {
                personDto.PersonImageRef = uploadedImage;

                if (personDto.PersonImageRef.Contains(personImagePath))
                {
                    personDto.PersonImageRef = personDto.PersonImageRef.Replace(personImagePath, string.Empty);
                }
                if (personDto.PersonImageRef.Contains("~/Content"))
                {
                    personDto.PersonImageRef = string.Empty;
                }
            }

            if (personDto.Id == 0)
            {
                personDto.GlobalEntityGUID = model.GlobalEntityGUID;

                personDto = CrmCoreRepository.AddPerson(personDto, null, null, null);

                if (personDto != null)
                {
                    personModel.GlobalEntityGUID = personDto.GlobalEntityGUID;

                    var personDetailModel = model.PersonDetailModel;
                    personDetailModel.PersonId = personDto.Id;

                    var personDetailDto = Mapper.MapTo<PersonDetailDto>(personDetailModel);
                    personDetailDto.CreatedBy = "Admin";
                    personDetailDto.UpdatedBy = "Admin";

                   personDetailDto = personDetailModel.Id == 0 ? CrmCoreRepository.AddPersonDetail(personDetailDto) : CrmCoreRepository.UpdatePersonDetail(personDetailDto);                
                }
            }
            else if (personDto.Id > 0)
            {
                personDto = CrmCoreRepository.UpdatePerson(personDto, null, null, null);

                if (personDto != null)
                {
                    personModel.GlobalEntityGUID = personDto.GlobalEntityGUID;

                    var personDetailModel = model.PersonDetailModel;
                    personDetailModel.PersonId = personDto.Id;

                    var personDetailDto = Mapper.MapTo<PersonDetailDto>(personDetailModel);
                    personDetailDto.CreatedBy = "Admin";
                    personDetailDto.UpdatedBy = "Admin";

                    personDetailDto = personDetailModel.Id == 0 ? CrmCoreRepository.AddPersonDetail(personDetailDto) : CrmCoreRepository.UpdatePersonDetail(personDetailDto);
                }
            }

            return RedirectToRoute("EditEntity", new { controller = "GlobalEntity", action = "EditEntity", entityGuid = personModel.GlobalEntityGUID, entityType = "P" });
        }

enter image description here

personImagePath如屏幕截图所示为null。因为我没有从测试中传递参数,所以我不知道如何使其包含值。我对单元测试中的操作有点困惑,以解决这个问题。任何帮助都会很棒。

1 个答案:

答案 0 :(得分:3)

您使用的是IImageRepository的两个不同实例。您需要对注入要测试的对象的相同对象进行Setup次调用(PersonController - IImageRepository)。

要解决此问题,请更改

var imageRepository = new Mock<IImageRepository>();
imageRepository.Setup(x => x.SaveImage(It.IsAny<HttpPostedFileBase>(),
    It.IsAny<ImagePaths>()));

到(注意Returns

_repoImage.Setup(x => x.SaveImage(It.IsAny<HttpPostedFileBase>(),
    It.IsAny<ImagePaths>())).Returns("~/Content");