ControllerContext.IsChildAction 调用失败,模拟行为严格。所有调用都必须有设置

发布于 2024-09-08 16:56:10 字数 2055 浏览 4 评论 0原文

我正在尝试学习如何对 ASP.NET MVC 控制器操作进行单元测试。具体来说,我试图模拟 ControllerContext,以便我可以测试访问 HttpContext.Current.User.Identity.Name 的操作。

我正在使用起订量。

一切进展顺利,直到我打开 MockBehavior.Strict。我知道如果代码无法调用我标记为“可验证”的内容,则会引发异常。显然,如果我不提供设置的“额外”方法(如 IsChildAction)没有被调用,它也会抛出异常。

[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();
...
}

这是我正在测试的控制器操作:

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

        return View();
    }

return View(); 时触发异常。语句被执行。错误消息告诉我,我需要一个设置方法来调用 IsChildAction,因此我将测试类更新为:

[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);            
    } 

...

之后,我收到了有关 ControllerContext.RouteData 没有设置方法的类似错误。通过排除过程,我最终可以为所有丢失的调用添加安装方法,但这似乎不对。也许我误解了 MockBehavior.Strict 的使用,但我认为您打开它是为了避免获取属性的默认值(例如我想要检查的 User 对象为 null)。我在这里缺少什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

终难遇 2024-09-15 16:56:10

如果有任何与预期不同的情况,严格的模拟将立即失败。所以这意味着,如果任何未在期望中指定的方法调用都会失败。另一方面,非严格的模拟忽略,这样的调用

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文