Gre*_*egH 3 .net c# asp.net unit-testing moq
我目前正在与 Moq 合作进行一些单元测试。我遇到了一个问题,我指定我的模拟对象返回什么,但实际调用返回 null 而不是我在.Returns(...). 我查看了其他帖子,其中一个建议是创建模拟MockBehavior.Strict- 这样做后,我收到一个相当详细的错误,如下所示:
IMyRepository.Save(MvcIndividualAuth.Data.Models.DTO.MyTableDTO) invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
但是,我正在对我的模拟对象已经调用的唯一方法调用 setup 。请看下面的代码:
我的测试:
MyService _myService;
Mock<IMyRepository> _myRepoMock;
[TestInitialize]
public void Setup()
{
_myRepoMock = new Mock<IMyRepository>();
_myService = new MyService(_myRepoMock.Object);
}
[TestMethod]
public void MyServiceSave()
{
//Arrange
var myDto = new MyTableDTO { Id = 1, Bar = 5, Foo = "Test" };
_myRepoMock.Setup(x => x.Save(myDto)).Returns(myDto);
//Act
var vm = _myService.Save(new MyTableViewModel(myDto));
//Assert
Assert.AreEqual(vm.Id, 1);
Assert.AreEqual(vm.Foo, "Test");
Assert.AreEqual(vm.Bar, 5);
Assert.AreEqual(vm.BarPlusFoo, "5 Test");
}
Run Code Online (Sandbox Code Playgroud)
MyService.Save方法:
public MyTableViewModel Save(MyTableViewModel viewModel)
{
var dto = MyTableViewModel.GetDto(viewModel);
var dbDto = _myRepo.Save(dto); //_myRepo is of type IMyRepository,
// this _myRepo.Save call is returning null
var vm = new MyTableViewModel(dbDto);
return vm;
}
Run Code Online (Sandbox Code Playgroud)
为什么我的测试中的模拟存储库没有返回我在调用中指定的值.Returns(..)?感谢所有帮助。
编辑:根据要求,这里是 MyRepository.Save 方法和 MyTableViewModel.GetDto():
我的存储库.保存:
public MyTableDTO Save(MyTableDTO dto)
{
try
{
var entity = new MyTable();
if (String.IsNullOrEmpty(dto.Foo))
{
throw new ArgumentException("MyTable requires Foo");
}
if (dto.Id == 0)
{
//added
entity.Update(dto);
_db.MyTables.Add(entity);
}
else
{
//modified
entity = _db.MyTables.Single(x => x.Id == dto.Id);
entity.Update(dto);
}
_db.SaveChanges();
return new MyTableDTO(entity);
}
catch (Exception)
{
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
MyTableViewModel.GetDto(..);
public static MyTableDTO GetDto(MyTableViewModel vm)
{
var dto = new MyTableDTO
{
Bar = vm.Bar,
Foo = vm.Foo,
Id = vm.Id
};
return dto;
}
Run Code Online (Sandbox Code Playgroud)
你得到的是null因为GetDto()返回对象不同于myDto- 引用是不同的。
您可以将您的更改Setup()为 return myDto:
_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns(myDto);
Run Code Online (Sandbox Code Playgroud)
或者,如果您想返回作为参数传递的对象:
_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns((MyTableDTO dto) => dto);
Run Code Online (Sandbox Code Playgroud)
或者,如果您想基于某些属性进行模拟:
_myRepoMock.Setup(x => x.Save(It.Is<MyTableDTO>(dto => dto.Id == 1))).Returns(myDto);
Run Code Online (Sandbox Code Playgroud)
或者如果你想修改返回结果:
_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns((MyTableDTO dto) => { dto.Id = 2; return dto;});
Run Code Online (Sandbox Code Playgroud)
您还可以结合所有方法。