【问题标题】:how to write a unit test to check returned items are of type list如何编写单元测试来检查返回的项目是列表类型
【发布时间】:2015-04-01 08:17:23
【问题描述】:

我是单元测试的新手,并且是在 NUnit 中使用 MOQ 框架的新手。我有一个控制器,它返回 ViewModel 对象列表作为

public ActionResult ValidateOutstandingItems()
{
        var entities = _itemsService.GetAll(true).Where(x => x.IsValid == null);
        var model = entities.Select(e => _mappingEngine.Map<ItemModel>(e));
        return View(model);
}

我需要编写一个单元测试来检查此操作方法返回的项目是否属于List&lt;ItemModel&gt;

我写过这样的东西

[Test]
    public void ValidateOutstandingItemsReturnsItemsViewModelList()
    {            
        var itemsService = new Mock<ItemsService>();
        var mapper = new Mock<IMappingEngine>();
        var itemsList = new List<itemModel>()
        {
            new itemModel{Id = 1,Name = "item 1"},
            new itemModel(){Id=2,Name="item 2"}

        };

        var controller = new ItemController(itemsService.Object, mapper.Object);
        // Act
        var result = controller.ValidateItems();

        // Assert
        var model = ((ViewResult)result).Model as List<ItemModel>;
        Assert.True(model.Count == 2);

    }

我们如何编写 setup 方法并执行 assert 来测试呢?谢谢

【问题讨论】:

    标签: asp.net-mvc nunit moq


    【解决方案1】:

    您的书面测试将随时失败,因为没有正确准备模拟。

    完整的设置如下所示:

    [Test]
    public void ValidateOutstandingItemsReturnsItemsViewModelList()
    {            
        var itemsService = new Mock<ItemsService>();
        var mapper = new Mock<IMappingEngine>();
        var itemsList = new List<itemModel>()
        {
            new itemModel{Id = 1,Name = "item 1"},
            new itemModel(){Id=2,Name="item 2"}
        };
        itemsService.Setup(s=>s.GetAll(true)).Returns(itemsList);
    
        var mapped1 = new ItemModel();
        var mapped2 = new ItemModel();
    
        mapper.Setup(m=>m.Map<ItemModel>(itemList[0])).Returns(mapped1);
        mapper.Setup(m=>m.Map<ItemModel>(itemList[1])).Returns(mapped2);
    
        var controller = new ItemController(itemsService.Object, mapper.Object);
        // Act
        var result = controller.ValidateItems();
    
        // Assert
        var model = ((ViewResult)result).Model as List<ItemModel>;
        //Verify that the model contains the 2 mapped elements
        CollectionAssert.AreEqual(model, new[]{mapped1, mapped2});
    }
    

    【讨论】:

      【解决方案2】:

      一种方法是在使用as List&lt;ItemModel&gt; cast 后检查模型对象是否为空。如果类型不是List&lt;ItemModel&gt;,则此语句后为空。

      [Test]
      public void ValidateOutstandingItemsReturnsItemsViewModelList()
      {            
          var itemsService = new Mock<ItemsService>();
          var mapper = new Mock<IMappingEngine>();
          var itemsList = new List<itemModel>()
          {
              new itemModel{Id = 1,Name = "item 1"},
              new itemModel(){Id=2,Name="item 2"}
      
          };
      
          var controller = new ItemController(itemsService.Object, mapper.Object);
          // Act
          var result = controller.ValidateItems();
      
          // Assert
          var model = ((ViewResult)result).Model as List<ItemModel>;
      
          // Test whether type is List<ItemModel>
          Assert.IsNotNull(model, "model is not of type List<ItemModel>");
          Assert.True(model.Count == 2);
      
      }
      

      【讨论】:

      • @NightOwn888 我们如何将itemsList 视为视图模型
      【解决方案3】:

      有一个名为 IsInstanceOfType 的方法

      [Test]
      public void ValidateOutstandingItemsReturnsItemsViewModelList()
      {            
          var itemsService = new Mock<ItemsService>();
          var mapper = new Mock<IMappingEngine>();
          var itemsList = new List<itemModel>()
          {
              new itemModel{Id = 1,Name = "item 1"},
              new itemModel(){Id=2,Name="item 2"}
      
          };
      
          var controller = new ItemController(itemsService.Object, mapper.Object);
          // Act
          var result = controller.ValidateItems();
      
          // Assert
          Assert.IsInstanceOfType(((ViewResult)result).Model, typeof(List<ItemModel>));
      
      }
      

      【讨论】:

        【解决方案4】:

        上面的实现几乎没有问题,但我想你会弄明白的(可能是你输入问题时的拼写错误)。您提到控制器返回 ViewModel (ItemViewModel) 对象列表,Service 将模型对象列表返回给控制器 (ItemModel),说要设置模拟对象,您可以尝试以下操作:

                // Setup itemService GetAll like this
                itemsService.Setup(m => m.GetAll(It.Is(true))).Returns(itemsList.ToArray());
        
                mapper.Setup(m => m.Map<ItemModel[], ItemViewModel[]>(It.IsAny<ItemModel[]>()))
                    .Returns(itemViewModelList.ToArray());
        

        断言:

                // Act
                var result = controller.ValidateOutstandingItems() as ViewResult;
        
                // Check number of items are correct
                var model = result.Model as List<ItemViewModel>;
                Assert.True(model.Count == 2);
        

        您必须在单元测试中创建 itemList 和 itemViewModelList。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多