Reputation: 416
Hello :) I'm a novice in using Moq framework with Unit and I have an issue in which, as I will demonstrate below, I'm trying to Moq a service call on a MVC Controller which takes Session objects as parameters. On my Unit test framework I create my object, set it up on the service call and I'm hoping to have it as the result of the response of the test to then Assert.
Problem: I tried to Mock HttpContext based on other solutions, which works because on the Controller side I get the values that I set on my Unit Test but upon SETUP of the service call (I have "Mock(MockBehavior.Strict);") when the debugger reaches the controller, upon the actual call I get an error saying that no SETUP was defined. Or if I take out the "MockBehavior.Strict", the "model" variable on the controller is always returning null and not the object I set it on the Unit Test class.
So here is my simple unit class,
[TestClass]
public class SearchControllerTest
{
#region Variables
Mock<ControllerContext> _controllerContext;
Mock<ISearchService> _serviceMock;
SearchController _controller;
#endregion
[TestInitialize]
public void SetUp()
{
// Arrange
_controllerContext = new Mock<ControllerContext>();
_serviceMock = new Mock<ISearchService>(MockBehavior.Strict);
_controller = new SearchController(_serviceMock.Object);
}
#region Success Test Cases
[TestMethod]
public void SearchListTest()
{
string pid = "val1";
string oid = "val2";
string lang = "val3";
string tid = "val4";
string pattern = "val5";
DocumentViewModel docModel = SetDocumentViewModel();
// Bypass
//_controllerContext.Setup(x => x.HttpContext.Session).Returns(_session.Object);
_controllerContext.SetupGet(p => p.HttpContext.Session["ProjectId"]).Returns("X");
_controllerContext.SetupGet(p => p.HttpContext.Session["OverlayId"]).Returns(string.Empty);
_controllerContext.SetupGet(p => p.HttpContext.Session["ProjectLanguage"]).Returns(string.Empty);
_controllerContext.SetupGet(p => p.HttpContext.Session["NodeId"]).Returns(string.Empty);
_controller.ControllerContext = _controllerContext.Object;
_serviceMock.Setup(x => x.FullTextSearchForAll(pid, oid, lang, tid, pattern)).Returns(docModel);
// Act
var result = _controller.SearchList(pid, oid, lang, tid, pattern) as PartialViewResult;
// Assert
Assert.AreEqual("#0Id", ((DocumentViewModel)result.Model).Rows[0].UID);
}
#endregion
#region Private
DocumentViewModel SetDocumentViewModel()
{
return new DocumentViewModel()
{
Columns = new Service.QueryResultColumn[]
{
new Service.QueryResultColumn
{
Alignment = ServiceConstants.Left,
Index = 0,
Visible = true,
Width = 3,
Header = ServiceConstants.Label
}
},
Properties = new DocumentsInfo[]
{
new DocumentsInfo()
{
IsCheckInAllowed = true,
IsCheckoutAllowed = true,
IsDocumentCheckedOut = false,
IsPlaceHolder = false,
IsUndoCheckoutAllowed = true,
lastVersionUid = "123"
}
},
Rows = new Service.QueryResultRow[]
{
new Service.QueryResultRow()
{
Children = null,
ExtensionData = null,
ImageSource = "Source",
Items = new Service.QueryResultItem[]
{
new Service.QueryResultItem()
{
ExtensionData = null,
ImageSource = "Src",
Text = "Txt",
UID = "uid"
}
},
UID = "#0Id"
}
}
};
}
#endregion
}
And here's my Controller,
public class SearchController : Controller
{
ISearchService _searchService;
public SearchController(ISearchService searchService) // I use UnityContainer
{
_searchService = searchService;
}
public PartialViewResult SearchList(string pid, string oid, string lang, string tid, string pattern)
{
ViewBag.ProjectId = pid;
ViewBag.OverlayId = oid;
ViewBag.ProjectLanguage = lang;
ViewBag.NodeId = tid;
ViewBag.Pattern = pattern;
DocumentViewModel model = null;
try
{
model = _searchService.FullTextSearchForAll(
Session["ProjectId"] as string,
Session["OverlayId"] as string,
Session["ProjectLanguage"] as string,
Session["ProjectId"] as string,
pattern
);
}
catch (Exception ex)
{
ViewBag.Error = ex.Message;
}
// Ajax.OnError() will handle the Custom Exception Error Message
if (ViewBag.Error != null)
throw new CustomtException((String)ViewBag.Error);
return PartialView(model);
}
}
Tank your for your patience and time. Have a nice day :)
Upvotes: 3
Views: 10927
Reputation: 2691
You've setup params in method with some values:
_serviceMock.Setup(x => x.FullTextSearchForAll(pid, oid, lang, tid, pattern)).Returns(docModel);
and trying to give Session variable as empty string
_controllerContext.SetupGet(p => p.HttpContext.Session["OverlayId"]).Returns(string.Empty);
it will never match. try setup service with It.IsAny() like
_serviceMock.Setup(x => x.FullTextSearchForAll(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Returns(docModel);
And if it will shout change session setup
Upvotes: 7
Reputation: 8562
I recommend creating consts for ProjectId, et. al., and then using them to setup your mocks, verify calls, and set the state of any objects. This ensures the value you expect (and only the value you expect) is used throughout.
Upvotes: 0