我是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属性“名称”为空,并且接收到controllerItemDetail属性名称为“更改名称”。

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


我的mockedItemDetail属性名称在当前作用域中也更新为“更改名称”,我不知道为什么?这是起订量的实际行为吗?


编辑内容

考虑下面的模拟列表中的上述情况,此处模拟对象的更改不会在所有上下文中都更新。也就是说,即使在测试方法调用之后,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);
}

最佳答案

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

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

07-25 23:29