使用Moq:Mock对象自动更新?

时间:2017-07-07 05:56:53

标签: c# unit-testing nunit moq moq-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”具有null并且接收到controllerItemDetail属性Name作为“Changed Name”。

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

  1. 我的mockedItemDetail属性名称在当前范围内也更新为“更改名称”,我不知道为什么?这是MoQ的实际行为吗?
  2. 编辑内容

    在下面的模拟列表中考虑相同的上述情况,这里模拟对象的更改不会在所有上下文中更新。即,在测试方法调用之后,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);
    }
    

1 个答案:

答案 0 :(得分:2)

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

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

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

快速跟进。要让它每次返回空白new ItemDetail(),您只需使用Returns()的lambda方法:

mockObject.Setup(x => x.GetItemDetail()).Returns(() => new ItemDetail()
{
    Name = null
});