开发者

ControllerContext.IsChildAction invocation failed with mock behavior Strict. All invocations must have a setup

I am toying around to learn how to unit test ASP.NET MVC controller actions. Specifically I'm trying to mock the ControllerContext so that I can test an action that accesses HttpContext.Current.User.Identity.Name.

I'm using Moq.

Things were going pretty well until I turned on MockBehavior.Strict. I knew that this would throw an exception if the code failed to call the thing that I marked Verifiable. Apparently, it will also throw an exception if "extra" methods where I don't provide a setup (like IsChildAction) don't get called.

[TestMethod]

public void Index_Get_AccessesUserIdentityName()
    {

// Arrange

var mock = new Mock<ControllerContext>(MockBehavior.Strict);

mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns("treycarroll").Verifiable();
HomeController controller = new HomeController();
controller.ControllerContext = mock.Object;

// Act
ViewResult result = controller.Index() as ViewResult;

/开发者_开发百科/ Assert
mock.Verify();
...
}

Here is the Controller action that I'm testing:

public ActionResult Index()
    {
        ViewData["Message"] = "Welcome to ASP.NET MVC!"+User.Identity.Name;

        return View();
    }

The exception is triggered when the return View(); statement is executed. The error message tells me that I need a setup method for the call to IsChildAction so I updated my test class to this:

[TestMethod] 

    public void Index_Get_AccessesUserIdentityName() 
    { 

        // Arrange 

        var mock = new Mock<ControllerContext>(MockBehavior.Strict); 

        string expectedUserName = "treycarroll";

        mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(expectedUserName).Verifiable();
        mock.SetupGet(m => m.IsChildAction).Returns(true).Verifiable();
        HomeController controller = new HomeController(); 
        controller.ControllerContext = mock.Object; 

        // Act 
        ViewResult result = controller.Index() as ViewResult;
        string actualUserName = controller.ControllerContext.HttpContext.User.Identity.Name;


        // Assert 
        mock.Verify();
        Assert.AreEqual(actualUserName, expectedUserName);
        Assert.IsNotNull(result);            
    } 

...

After which I get a similar error about no setup method for ControllerContext.RouteData. By process of elimination I could wind up adding Setup methods for all the missing calls, but this doesn't seem right. Maybe I'm misunderstanding the use of MockBehavior.Strict, but I thought that you turn this on in order to avoid getting default values for your properties (such as null for the User object that I want to inspect). What am I missing here?


A strict mock will fail immediately if anything differs from the expectations. So this means, that if any method call not specified in expectation will fail. On the other hand, a non-strict mock ignore, such calls

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜