如何编写单元测试来检查返回的项目是类型列表

时间:2015-03-23 13:36:57

标签: asp.net-mvc nunit moq

我是单位测试和使用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<ItemModel>

我写过类似的东西

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

    }

我们如何编写设置方法并执行断言来测试它?感谢

4 个答案:

答案 0 :(得分:2)

执行此操作的一种方法是在使用as List<ItemModel>强制转换后检查模型对象是否为空。如果类型不是List<ItemModel>,则在此语句后它将为null。

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

}

答案 1 :(得分:2)

您所写的测试将随时失败,因为模拟准备不正确。

完整的设置如下:

[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 :(得分:1)

有一个名为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>));

}

答案 3 :(得分:0)

上面的实现几乎没有问题,但我认为你会弄清楚(当你输入问题时可能会出现拼写错误)。你提到控制器返回一个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。