Using Moq: Updating Mock Object Automatically?
I am new to MoQ framework. I am writing unit testing for a 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);
}
Testing is in progress and now I want to assert the posted mockedItemDetail and the resulting controller of the result of the model ItemDetail.
In the above case, the mockedItemDetail property "Name" is null and the name of the controllerItemDetail property is retrieved as "Modified Name".
But whenever I debug, after calling the GetDetails () test method,
- The mockedItemDetail Name property is also updated as "Modified Name" in the current scope and I don't know why? Is this the actual behavior of MoQ?
Edited content
Consider the same example in the list below, here a change to a mock will not update in all contexts. those. the number of lists for mockedItemDetailList remains 0, and the number of lists for the controller ItemDetail is 1 even after calls to the test method. 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);
}
source to share
You have a very specific object:
var mockedItemDetail = new ItemDetail()
{
Name = null
};
When you call mockObject.Setup(x => x.GetItemDetail()).Returns(mockedItemDetail);
, you return a reference to mockItemDetail
. Any changes to this object will be updated in all contexts.
Quick observation. To make it return empty every time new ItemDetail()
, you can simply use a lambda method Returns()
:
mockObject.Setup(x => x.GetItemDetail()).Returns(() => new ItemDetail()
{
Name = null
});
source to share