Webapi 控制器单元测试中的 Automapper
Automapper in Webapi Controller Unit test
我的 webapi 项目中有一个控制器方法,它调用服务方法并将服务方法的响应转换为 Dto 对象以发送响应。
控制器看起来像这样:
[HttpPost]
[Route(WebApiConfig.RootApiUri + "/v1/examplepost")]
public async Task<List<Html1Dto>> examplepost([FromBody] SomeInfoDto someInfoDto)
{
var someInfo = _mapper.Map<SomeInfoDto, SomeInfo>(someInfoDto);
return this._mapper.Map<List<Html1>, List<Html1Dto>>(await this._someService.SomeCall(someInfo));
}
模拟测试是这样的:
//Arrange
var mockMapper = new Mock<IMapper>();
var mockSomeService = new Mock<ISomeService<Html1>>();
mockSomeService.Setup(s => s.SomeCall(It.IsAny<SomeInfo>())).ReturnsAsync(
new List<Html1>() {new Html1() {....}});
SomeInfoDto mockSomeInfoDto = new SomeInfoDto()
{
..
};
SomeInfo mockSomeInfo = new SomeInfo();
mockMapper.Setup(m => m.Map<SomeInfoDto, SomeInfo>(mockSomeInfoDto))
.Returns(mockSomeInfo);
mockMapper.Setup(m => m.Map<List<Html1>, List<Html1Dto>>(It.IsAny<List<Html1>>())).Returns(It.IsAny<List<Html1Dto>>);
var someController = GetController(mockMapper.Object, mockSomeService.Object);
//Act
var result = await someController.examplePost(mockSomeInfoDto);
我正在使用自动映射器通过 Dtos 映射对象。当我调试这个测试时,结果为空。传入 dto 的映射工作正常。我怀疑服务方法设置存在一些问题。感谢任何帮助。
你的映射器模拟是相反的
mockMapper.Setup(m => m.Map<List<Html1>, List<Html1Dto>>(It.IsAny<List<Html1>>())).Returns(It.IsAny<List<Html1Dto>>);
到方法中的签名
this._mapper.Map<List<Html1Dto>, List<Html1>>(await this._someService.SomeCall(someInfo));
此外,假设这在您的实际代码中是正确的,那么可能导致您出现问题的另一个原因是 return It.IsAny<List<Html1Dto>>
将为 null,因为 default(List<HtmlDto>)
是null,return 一个具体的 class 如下所示。
这次通话:
this._mapper.Map<List<Html1Dto>, List<Html1>>(await this._someService.SomeCall(someInfo));
在单元测试中没有设置,因此 return 将为 null。你需要安排它,可能是这样的:
mockMapper.Setup(m => m.Map<List<Html1Dto>, List<Html1>>(It.IsAny<List<Html1>>()))
.ReturnsAsync(new List<Html1Dto> { ... });
我的 webapi 项目中有一个控制器方法,它调用服务方法并将服务方法的响应转换为 Dto 对象以发送响应。 控制器看起来像这样:
[HttpPost]
[Route(WebApiConfig.RootApiUri + "/v1/examplepost")]
public async Task<List<Html1Dto>> examplepost([FromBody] SomeInfoDto someInfoDto)
{
var someInfo = _mapper.Map<SomeInfoDto, SomeInfo>(someInfoDto);
return this._mapper.Map<List<Html1>, List<Html1Dto>>(await this._someService.SomeCall(someInfo));
}
模拟测试是这样的:
//Arrange
var mockMapper = new Mock<IMapper>();
var mockSomeService = new Mock<ISomeService<Html1>>();
mockSomeService.Setup(s => s.SomeCall(It.IsAny<SomeInfo>())).ReturnsAsync(
new List<Html1>() {new Html1() {....}});
SomeInfoDto mockSomeInfoDto = new SomeInfoDto()
{
..
};
SomeInfo mockSomeInfo = new SomeInfo();
mockMapper.Setup(m => m.Map<SomeInfoDto, SomeInfo>(mockSomeInfoDto))
.Returns(mockSomeInfo);
mockMapper.Setup(m => m.Map<List<Html1>, List<Html1Dto>>(It.IsAny<List<Html1>>())).Returns(It.IsAny<List<Html1Dto>>);
var someController = GetController(mockMapper.Object, mockSomeService.Object);
//Act
var result = await someController.examplePost(mockSomeInfoDto);
我正在使用自动映射器通过 Dtos 映射对象。当我调试这个测试时,结果为空。传入 dto 的映射工作正常。我怀疑服务方法设置存在一些问题。感谢任何帮助。
你的映射器模拟是相反的
mockMapper.Setup(m => m.Map<List<Html1>, List<Html1Dto>>(It.IsAny<List<Html1>>())).Returns(It.IsAny<List<Html1Dto>>);
到方法中的签名
this._mapper.Map<List<Html1Dto>, List<Html1>>(await this._someService.SomeCall(someInfo));
此外,假设这在您的实际代码中是正确的,那么可能导致您出现问题的另一个原因是 return It.IsAny<List<Html1Dto>>
将为 null,因为 default(List<HtmlDto>)
是null,return 一个具体的 class 如下所示。
这次通话:
this._mapper.Map<List<Html1Dto>, List<Html1>>(await this._someService.SomeCall(someInfo));
在单元测试中没有设置,因此 return 将为 null。你需要安排它,可能是这样的:
mockMapper.Setup(m => m.Map<List<Html1Dto>, List<Html1>>(It.IsAny<List<Html1>>()))
.ReturnsAsync(new List<Html1Dto> { ... });