【发布时间】:2014-12-18 23:46:37
【问题描述】:
我正在尝试使用 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" });
}
截图中显示的personImagePath为空。因为我没有从我的测试中传递一个参数,所以我不知道如何让它包含一个值。我对在单元测试中如何解决这个问题感到有点困惑。任何帮助都会很棒。
【问题讨论】:
-
在我看来
_imageRepository.SaveImage()是罪魁祸首。您设置它,但从不指定.Returns()(.Contains()测试需要。Moq 可能返回 null 是缺少指定值。
标签: c# unit-testing model-view-controller moq