Praveen
Praveen

Reputation: 841

Using Moq : Mock object update automatically?

I am new to MoQ framework. I am writing unit testing for controller using MoQ framework and here is my test method,

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

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

        var result = myController.GetDetails() as ViewResult;

Here is my Controller Method,

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

Test runs and now I want to assert the sent mockedItemDetail and received model result controllerItemDetail.

In above case, mockedItemDetail property "Name" has null and received controllerItemDetail property Name as "Changed Name".

But whenever I debug, after calling the test method GetDetails(),

  1. My mockedItemDetail property Name is also updated as "Changed Name" in the current scope and I don't know why? Is this is the actual behavior of MoQ?

Edited Content

Consider the same above case in below mock list, here the change in the mock object will not update in all contexts. i.e. The list count for mockedItemDetailList remains 0 and the list count of controllerItemDetail is 1 even after test method calls. Why?

Test method:

var mockedItemDetailList = new List<ItemDetail>();

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

    var result = myController.GetDetails() as ViewResult;

Controller method:

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

Upvotes: 3

Views: 2476

Answers (1)

Blue
Blue

Reputation: 22921

You have a very specific object:

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

When you call mockObject.Setup(x => x.GetItemDetail()).Returns(mockedItemDetail);, you're returning the reference to mockItemDetail. Any changes on that object will update in all contexts.

A quick follow up. To have it return a blank new ItemDetail() each time, you can simply use the lambda method of Returns():

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

Upvotes: 2

Related Questions