【问题标题】:Cannot return nonempty string in mocking a function using Moq in ASP.NET MVC unit testing在 ASP.NET MVC 单元测试中使用 Moq 模拟函数时无法返回非空字符串
【发布时间】:2016-05-02 22:07:02
【问题描述】:

我正在开发一个 ASP.NET 项目。我正在我的项目中进行单元测试。所以我使用了微软构建的单元测试框架。我正在使用 Moq 在单元测试中模拟数据。但是我在模拟一个使用 Moq 返回字符串值的函数时遇到了问题。那么问题是它总是返回空,即使我模拟它返回非空字符串。

这是我要测试的控制器和操作:

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);
    }

}

我评论了我的代码中存在问题的地方。

这是我的测试代码:

[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");
        }

如您所见,上面的代码应该是失败的,因为我没有为文件上传功能返回空。此外,我还评论了创建功能以确保问题。我还以多种方式进行了测试,以确保问题来自那里。为什么会这样?为什么 mock 方法总是返回空字符串?通过上面的代码测试应该失败,因为我返回了“XXX”。如何返回非空值?

【问题讨论】:

    标签: c# asp.net asp.net-mvc unit-testing


    【解决方案1】:

    您不想将 It.Is 用于 return 语句,您希望将其设置为您真正想要返回的内容。

                fileHelperMock.Setup(m => m.UploadFile(model.ImageFile, It.Is<string>(y=>y=="Directory"), null)).Returns("XXX");
    

    我试过这种方式。 fileHelperMock.Setup(m => m.UploadFile(model.ImageFile, It.Is(y => y == "Uploads/Images"), null)).Returns("something"); .不是 It.Is(x=>x=="XXX") 作为回报。但“上传/图像”仅适用。当我传递其他值时,它不起作用。请问为什么?

    这是因为您将“目录”的值硬编码到设置中,试试这个:

    fileHelperMock.Setup(m => m.UploadFile(model.ImageFile, It.IsAny<string>(), null)).Returns("XXX");
    

    【讨论】:

      【解决方案2】:

      问题是目录的参数:

      fileHelperMock.Setup(m => m.UploadFile(model.ImageFile, It.Is<string>(y=>y=="Uploads/Images"), null)).Returns(It.Is<string>(x=>x=="XXX"));
      

      【讨论】:

      • 我尝试通过更改参数值。还是行不通。即使返回值不为空,测试也不会失败。
      • 我试过这种方式。 fileHelperMock.Setup(m => m.UploadFile(model.ImageFile, It.Is(y => y == "Uploads/Images"), null)).Returns("something"); .不是 It.Is(x=>x=="XXX") 作为回报。但“上传/图像”仅适用。当我传递其他值时,它不起作用。请问为什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-14
      • 2014-01-18
      • 2011-05-04
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多