【问题标题】:Automapper in Webapi Controller Unit testWebapi 控制器单元测试中的 Automapper
【发布时间】:2016-05-31 11:50:38
【问题描述】:

我的 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);

我正在使用 automapper 将对象与 Dtos 进行映射。当我调试这个测试时,结果为空。传入 dto 的映射工作正常。我怀疑服务方法设置存在一些问题。任何帮助表示赞赏。

【问题讨论】:

  • 一件快速的事情 - 不要模拟 AutoMapper。真的,毫无意义。这就像嘲笑 JSON.Net 或 StringBuilder。就用真品吧。

标签: c# asp.net-web-api mocking asp.net-web-api2 automapper


【解决方案1】:

你的映射器模拟是相反的

mockMapper.Setup(m =&gt; m.Map&lt;List&lt;Html1&gt;, List&lt;Html1Dto&gt;&gt;(It.IsAny&lt;List&lt;Html1&gt;&gt;())).Returns(It.IsAny&lt;List&lt;Html1Dto&gt;&gt;);

到方法中的签名

this._mapper.Map&lt;List&lt;Html1Dto&gt;, List&lt;Html1&gt;&gt;(await this._someService.SomeCall(someInfo));

此外,假设在您的实际代码中是正确的,那么可能导致您出现问题的另一位是返回 It.IsAny&lt;List&lt;Html1Dto&gt;&gt; 将是 null,因为 default(List&lt;HtmlDto&gt;) 是 null,而是返回一个具体的类,如下所示.


这个电话:

this._mapper.Map<List<Html1Dto>, List<Html1>>(await this._someService.SomeCall(someInfo));

在单元测试中没有设置,因此将返回 null。你需要安排它,可能是这样的:

mockMapper.Setup(m => m.Map<List<Html1Dto>,  List<Html1>>(It.IsAny<List<Html1>>()))
.ReturnsAsync(new List<Html1Dto> { ... });

【讨论】:

  • 我的测试中已经有这样的代码,忘记添加问题,它也不适用于这个。我已经编辑了问题
  • 你有完整的例子可以分享吗?
  • 我无法发布确切的原始代码,因此我伪造了它。除了提到的对象外,代码几乎相同。如果您需要任何额外信息,请发表评论,我会在问题中添加。
  • 如果你将 await this._someService.SomeCall(someInfo) 移动到上面一行的变量中,然后将该变量传递给 .Map 方法呢?
  • @stu :我仍然从您提到的修复中得到 null 的结果。感谢您的回复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多