【问题标题】:Moq: How to mock method with `complex type` parameterMoq:如何使用“复杂类型”参数模拟方法
【发布时间】:2018-05-11 20:21:19
【问题描述】:

原标题:

起订量:使用out parameter 的模拟方法方法返回空数组

问题不在于out parameter,而在于complex type AlbumFiltercomplex type parameter albumFilters。有关详细信息,请参阅我的答案。

我让 Moq 为没有 out parameter 的方法工作,但是当我尝试使用 out parameter 的 Moq 时,它返回一个空数组。

GetAllAlbums_ok_returnsdata_test() 通过。 GetAllAlbumsPaged_test() 失败。在AlbumApiController 中的GetAllAlbumsPaged 方法中对_inventoryService 的调用返回一个空数组Album[]

我查看了有关使用 out argumentsMoq Quickstart 部分。

// 输出参数

var outString = "ack";

// TryParse 将返回 true,out 参数将返回“ack”, 懒评估

mock.Setup(foo => foo.TryParse("ping", outString)).Returns(true);

测试类:

[Fact]
public void GetAllAlbums_ok_returnsdata_test() {
  Mock<IInventoryService> mockInventoryService
                      = new Mock<IInventoryService>();
  Album[] albums = { new Album { AlbumId = 1 },
    new Album { AlbumId = 2 } };
  mockInventoryService.Setup(obj => obj.GetAllAlbums()).Returns(albums);

  AlbumApiController controller = new AlbumApiController(mockInventoryService.Object);

  IHttpActionResult response = controller.GetAllAlbums();
  var contentResult = response as OkNegotiatedContentResult<Album[]>;
  Assert.NotNull(contentResult);
  Assert.NotNull(contentResult.Content);
  var data = contentResult.Content;
  Assert.Equal(data, albums); }

[Fact]
public void GetAllAlbumsPaged_test() {
  Mock<IInventoryService> mockInventoryService
                      = new Mock<IInventoryService>();
  Album[] albums = new Album[20];
    for (int i = 0; i < 20; i++) albums[i] = new Album { AlbumId = i + 1 };
  var albumFilter = new AlbumFilter { AlbumNumber = "", Artist = "",
      Title = "", Genre = 0, Price = 0, StockAmount = 0 };
  var sortItems = new List<SortItem>(); 
  int totalCount;

  mockInventoryService.Setup(obj => obj.GetAllAlbumsPaged(out totalCount, albumFilter,
        sortItems, 0, 4)).Returns(albums);

  AlbumApiController controller = new AlbumApiController(mockInventoryService.Object);

  IHttpActionResult response = controller.GetAllAlbumsPaged(Json.Encode(albumFilter),
        Json.Encode(sortItems), 0, 4);
  var contentResult = response as OkNegotiatedContentResult<object>;
  Assert.NotNull(contentResult); }

AlbumApiController:

public class AlbumApiController : ApiController
  {
    private readonly IInventoryService _inventoryService;

    public AlbumApiController(IInventoryService inventoryService)
    { _inventoryService = inventoryService; }

    [HttpGet]
    [Route("getallalbums")]
    public IHttpActionResult GetAllAlbums() {
      return GetHttpResponse(Request, () => {
        var albums = _inventoryService.GetAllAlbums();
        return Ok(albums); }); }


    [HttpGet]
    [Route("getallalbumspaged/{pageIndex}/{pageSize}")]
    public IHttpActionResult GetAllAlbumsPaged(string filters, string sorts,
          int pageIndex, int pageSize) { 
      var _filters = JsonConvert.DeserializeObject<AlbumFilter>(filters);
      var _sorts = JsonConvert.DeserializeObject<List<SortItem>>(sorts);
      return GetHttpResponse(Request, () => {
        int totalCount;
        var albums = _inventoryService.GetAllAlbumsPaged(out totalCount, _filters,
          _sorts, pageIndex, pageSize);
        var albums_Count = new { albums, totalCount };
        return Ok(albums_Count); }); } }

更新:

我将此测试方法添加到AlbumAPIController

[HttpGet]
public IHttpActionResult GetTest(int intTest)
{
  return GetHttpResponse(Request, () => {
    int testInt;
    var albums = _inventoryService.GetTest(out testInt, intTest);
    return Ok(albums);
  });
}

这个测试到测试类:

[Fact]
public void GetTest_test() {
  Mock<IInventoryService> mockInventoryService
                = new Mock<IInventoryService>();
  Album[] albums = new Album[20];
  for (int i = 0; i < 20; i++) albums[i] = new Album { AlbumId = i + 1 };
  int testInt = 15;
  mockInventoryService.Setup(obj => obj.GetTest(out testInt, 5)).Returns(albums);

  AlbumApiController controller = new AlbumApiController(mockInventoryService.Object);
  IHttpActionResult response = controller.GetTest(5);
  var contentResult = response as OkNegotiatedContentResult<Album[]>;

  Assert.NotNull(contentResult);
  Assert.NotNull(contentResult.Content);
  var data = contentResult.Content;
  Assert.Equal(data, albums); }

测试通过并且 testInt 在 GetTest 方法中更新,所以问题似乎不在于“out 参数”。

根据 Diana 的故障排除建议,我将其添加到 GetAllAlbumsPaged 方法(紧跟在 JsonConverts 之后)以确保问题不在于 JSON

  _filters = new AlbumFilter { AlbumNumber = "", Artist = "",
      Title = "", Genre = 0, Price = 0, StockAmount = 0 };
  _sorts = new List<SortItem>();

_inventoryService.GetAllAlbumsPaged 方法的调用仍然返回一个空数组Albums[]

【问题讨论】:

  • 问题可能不在 out 参数中,而在其他参数中,albumFiltersortItems。要确认这一点,请暂时从您的方法中删除 out 参数并检查测试是否仍然失败。在这种情况下,检查JsonConvert.DeserializeObject&lt;AlbumFilter&gt;(Json.Encode(albumFilter)) 是否完全等于您的albumFilter 变量。对sortItems 执行相同操作。我怀疑没有调用模拟方法,因为参数值不匹配。
  • @Diana 很好的故障排除建议。虽然没有修好。请参阅 OP 中的更新。
  • 很高兴它有帮助!

标签: c# moq


【解决方案1】:

out parameter 不是问题所在。 complex type 参数 AlbumFilter 是问题所在。 Moq 显然不喜欢 complex type。我可以通过传递It.IsAny&lt;AlbumFilter&gt;() 而不是AlbumFilteralbumFilter 的实例来更改mockInventoryService 设置来使其工作。

 mockInventoryService.Setup(obj => obj.GetAllAlbumsPaged(out totalCount,
                      It.IsAny<AlbumFilter>(), sortItems, 0, 4)).Returns(albums);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 2011-01-12
    • 1970-01-01
    • 2014-01-08
    • 2016-09-21
    • 2011-04-17
    • 2010-10-08
    相关资源
    最近更新 更多