3

我是 MoQ 框架的新手。我正在使用 MoQ 框架为控制器编写单元测试,这是我的测试方法,

var mockedItemDetail = new ItemDetail()
        {
            Name = null
        };

        var mockObject = new Mock<IItem>();
        mockObject.Setup(x => x.GetItemDetail()).Returns(mockedItemDetail);

        var result = myController.GetDetails() as ViewResult;

这是我的控制器方法,

public ActionResult GetDetails()
    {
        var controllerItemDetail = new ItemDetail();
        controllerItemDetail = _item.GetItemDetail();
        controllerItemDetail.Name = "Changed Name";
        return View("ViewName", controllerItemDetail);
    }

测试运行,现在我想断言发送的 mockedItemDetail 和接收的模型结果 controllerItemDetail。

在上述情况下,mockedItemDetail 属性“Name”为空,并且接收到的 controllerItemDetail 属性 Name 为“Changed Name”。

但是每当我调试时,调用测试方法GetDetails()后,

  1. 我的 mockedItemDetail 属性 Name 在当前范围内也更新为“Changed Name”,我不知道为什么?这是 MoQ 的实际行为吗?

编辑内容

在下面的模拟列表中考虑与上述相同的情况,这里模拟对象的更改不会在所有上下文中更新。即 mockedItemDetailList 的列表计数保持为 0,即使在测试方法调用之后,controllerItemDetail 的列表计数仍为 1。为什么?

测试方法:

var mockedItemDetailList = new List<ItemDetail>();

    var mockObject = new Mock<IItem>();
    mockObject.Setup(x => x.GetListOfItemDetail()).Returns(mockedItemDetailList);

    var result = myController.GetDetails() as ViewResult;

控制器方法:

    public ActionResult GetDetails()
{
    var controllerItemDetail = new ItemDetail();
    controllerItemDetail = _item.GetListOfItemDetail();
    controllerItemDetail.Add(new ItemDetail(){
    Name = "Changed Name"
    });
    return View("ViewName", controllerItemDetail);
}
4

1 回答 1

2

你有一个非常具体的对象:

var mockedItemDetail = new ItemDetail()
{
    Name = null
};

当您调用 时mockObject.Setup(x => x.GetItemDetail()).Returns(mockedItemDetail);,您将返回对 的引用mockItemDetail。该对象的任何更改都将在所有上下文中更新。

快速跟进。要让它new ItemDetail()每次都返回一个空白,您可以简单地使用 lambda 方法Returns()

mockObject.Setup(x => x.GetItemDetail()).Returns(() => new ItemDetail()
{
    Name = null
});
于 2017-07-07T06:02:10.050 回答