lundi 2 mai 2016

Cannot return nonempty string in mocking a function using Moq in ASP.NET MVC unit testing

I am developing a ASP.NET project. I am doing unit testing in my project. So I used built unit testing framework by Microsoft. I am using Moq to mock data in Unit Test. But I am having a problem a mocking a function that return string value using Moq. Then problem is it always returning empty even I mocked it to return nonempty string. Please check my scenario below.

This is my controller and action to be tested

public class RegionController : Controller
    {
        private IRegionRepo regionRepo;

        private IFileHelper fileHelper;

        private int RecordPerPage;

        public RegionController(IRegionRepo regionParam,IFileHelper fileParam,int recordPerPage = 0)
        {
            this.regionRepo = regionParam;
            this.RecordPerPage = (recordPerPage == 0) ? AppConfig.RecordPerPage : recordPerPage;
            this.fileHelper = fileParam;
        }


    [HttpPost]
    public ActionResult Create(CreateRegionVM model)
    {
        if(model.ImageFile==null || model.ImageFile.ContentLength<1)
        {
            ModelState.AddModelError("ImagePath", "Image file is required");
        }

        if(ModelState.IsValid)
        {
            Region region = new Region
            {
                Name = model.Name,
                MmName = model.MmName,
                MmDescription = model.MmDescription,
                Description = model.Description,
                GeoLocation = model.GeoLocation
            };
            try
            {
                 region.ImagePath = fileHelper.UploadFile(model.ImageFile, "Uploads/Images");
            }
            catch
            {
                return new HttpStatusCodeResult(500);
            }

            if(String.IsNullOrEmpty(region.ImagePath))
            {
                return new HttpStatusCodeResult(500); // problem is here. always reach here even if I returned nonempty value from fileUpload function
            }

            //regionRepo.Create(region);


            return RedirectToAction("Create");
        }
        return View(model);
    }

}

I commented where problem exists in my code.

This is my testing code

[TestMethod]
        public void Cannot_Create_If_Upload_Fail()
        {
            var file = new Mock<HttpPostedFileBase>();
            file.Setup(m => m.ContentLength).Returns(1);
            CreateRegionVM model = new CreateRegionVM();
            model.ImageFile = file.Object;
            Mock<IRegionRepo> regionRepoMock = new Mock<IRegionRepo>();
            regionRepoMock.Setup(m => m.Create(new Region())).Returns(new Region());
            Mock<IFileHelper> fileHelperMock = new Mock<IFileHelper>();

            //here I did not returned empty string. So test should be failed. 
            fileHelperMock.Setup(m => m.UploadFile(model.ImageFile, It.Is<string>(y=>y=="Directory"), null)).Returns(It.Is<string>(x=>x=="XXX"));

            RegionController controller = new RegionController(regionRepoMock.Object, fileHelperMock.Object, 3);
            var unknownView = controller.Create(model);
            Assert.IsInstanceOfType(unknownView, typeof(HttpStatusCodeResult), "View type is wrong");
            HttpStatusCodeResult view = unknownView as HttpStatusCodeResult;
            Assert.AreEqual(view.StatusCode, 500, "Status code is not 500 when upload error");
        }

As you can see, the above code should be failed cause I did not return empty for file upload function. Besides, I also commented the create function to make sure the problem. I also tested in several ways to make sure the problem came from there. So please why is that happening? Why is the mock method always returning empty string? By the above code test should be failed caused I returned "XXX". Please how can I return nonempty value?

Aucun commentaire:

Enregistrer un commentaire