简体   繁体   English

Moq:如何使用“复杂类型”参数模拟方法

[英]Moq: How to mock method with `complex type` parameter

Original title: 原标题:

Moq: Mocking method method with out parameter returns empty array Moq:具有out parameter模拟方法方法返回空数组

The problem was not with the out parameter but with the complex type parameter albumFilters of complex type AlbumFilter . 问题是不与out parameter ,但与complex type parameter albumFilterscomplex type AlbumFilter See my Answer for details. 有关详细信息,请参见我的答案。

I have Moq working for a method without an out parameter but when I try and Moq with an out parameter it returns an empty array. 我让Moq正在为没有out parameter的方法工作,但是当我尝试和带有out parameter Moq时,它将返回一个空数组。

The GetAllAlbums_ok_returnsdata_test() passes. GetAllAlbums_ok_returnsdata_test()通过。 The GetAllAlbumsPaged_test() fails. GetAllAlbumsPaged_test()失败。 The call to the _inventoryService in the GetAllAlbumsPaged method in the AlbumApiController returns an empty array Album[] . _inventoryServiceGetAllAlbumsPaged方法中对AlbumApiController返回一个空数组Album[]

I've looked at the Moq Quickstart section on using out arguments . 我已经看过Moq快速入门部分中有关使用out arguments

// out arguments //输出参数

var outString = "ack"; var outString =“ ack”;

// TryParse will return true, and the out argument will return "ack", lazy evaluated // TryParse将返回true,而out参数将返回“ ack”,这是延迟计算的

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

Test Class: 测试类别:

[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: 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); }); } }

Update: 更新:

I added this test method to the AlbumAPIController : 我将此测试方法添加到AlbumAPIController

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

and this test to the test class: 并将此测试添加到测试类中:

[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); }

The test passed and the testInt was updated in the GetTest method so the problem doesn't seem to be with the 'out parameter`. 测试通过,并且在GetTest方法中更新了GetTest因此问题似乎不在于“ out参数”。

Per Diana's troubleshooting suggestion I added this to the GetAllAlbumsPaged method (right after the JsonConverts ) to ensure the issue wasn't with the JSON . 根据Diana的故障排除建议,我将其添加到GetAllAlbumsPaged方法中( JsonConverts ),以确保问题不在于JSON

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

The call to the _inventoryService.GetAllAlbumsPaged method still returns an empty array, Albums[] . _inventoryService.GetAllAlbumsPaged方法的调用仍返回空数组Albums[]

The out parameter was not the problem. out parameter不是问题。 The complex type parameter AlbumFilter was the problem. 问题是complex type参数AlbumFilter Moq apparently didn't like the complex type . Moq显然不喜欢complex type I was able to get it to work by changing the mockInventoryService setup by passing It.IsAny<AlbumFilter>() instead of the instance of the AlbumFilter , albumFilter . 我可以通过传递It.IsAny<AlbumFilter>()而不是AlbumFilter albumFilter实例来更改mockInventoryService设置,从而使其工作。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM