3

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 :)

4

2 回答 2

7

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

于 2013-04-16T15:49:15.807 回答
0

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.

于 2013-04-16T15:51:31.987 回答