测试 Asp.net MVC 应用程序时 Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression 失败

发布于 2024-09-26 07:34:51 字数 1675 浏览 3 评论 0原文

所以我正在尝试对控制器方法进行单元测试。我在 VS 2010 中使用 MSTest,Moq 3.1

测试方法:

    [TestMethod]
    public void TestAccountSignup()
    {
        var request = new Mock<HttpRequestBase>();
        var context = new Mock<HttpContextBase>();

        AccountController controller = new AccountController();
        controller.ControllerContext = new System.Web.Mvc.ControllerContext(context.Object, new RouteData(), controller);

        request.Setup(x => x.Cookies).Returns(new HttpCookieCollection());

        context.Setup(x => x.Request).Returns(request.Object);

        string username = StringHelper.GenerateRandomAlpha(10);

        var res = controller.Register(username, "foozbaaa+" + username + "@example.com", null, true, "Testing!", null);
    }

我的控制器方法:

   [CaptchaValidator]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Register(string userName, string email,string existingUsername, bool captchaValid, string heardAbout, string heardAboutOther)
    {
      //Loads of stuff here....

        //cool - all registered
       //This line gives the problem
     return new RedirectResult(this.BuildUrlFromExpression<AccountController>(x => x.AccountCreated()));
     }

控制器方法在不进行单元测试时工作得很好。

当以这种方式模拟和调用时,我在最后一行得到 System.Security.VerificationException:

Method Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression: type argument 'TController'违反了类型参数'TController'的约束。

现在显然 AccountController 是 TController 类型,否则在不进行单元测试时它将无法工作。它继承自我的 BaseController,而我的 BaseController 继承自常规 C​​ontroller。

由于嘲笑,我感觉这个错误是一个转移注意力的错误 - 有什么想法吗?

非常感谢。

So I'm trying to unit-test a controller method. I'm using MSTest in VS 2010, and Moq 3.1

Test method:

    [TestMethod]
    public void TestAccountSignup()
    {
        var request = new Mock<HttpRequestBase>();
        var context = new Mock<HttpContextBase>();

        AccountController controller = new AccountController();
        controller.ControllerContext = new System.Web.Mvc.ControllerContext(context.Object, new RouteData(), controller);

        request.Setup(x => x.Cookies).Returns(new HttpCookieCollection());

        context.Setup(x => x.Request).Returns(request.Object);

        string username = StringHelper.GenerateRandomAlpha(10);

        var res = controller.Register(username, "foozbaaa+" + username + "@example.com", null, true, "Testing!", null);
    }

My controller method:

   [CaptchaValidator]
    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Register(string userName, string email,string existingUsername, bool captchaValid, string heardAbout, string heardAboutOther)
    {
      //Loads of stuff here....

        //cool - all registered
       //This line gives the problem
     return new RedirectResult(this.BuildUrlFromExpression<AccountController>(x => x.AccountCreated()));
     }

The controller method works just fine when not unit testing.

When mocking and calling in this way, I get a System.Security.VerificationException on that last line:

Method Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression: type argument 'TController' violates the constraint of type parameter 'TController'.

Now clearly AccountController is of type TController, otherwise it wouldn't work when not unit-testing. It inherits from my BaseController, which inherits from the regular Controller.

I get the feeling this error is a red-herring, due to the mocking - any ideas why?

Many thanks.

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

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

发布评论

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

评论(2

我一直都在从未离去 2024-10-03 07:34:51

这是因为 Futures 使用稍微不同的控制器类型。

我不确定具体情况,但我遇到了同样的问题。它要么是 future 控制器与 MVC 2 控制器,要么是 MVC 1 控制器与 MVC 2 控制器。

查看完全限定类型名称是否有帮助。

This is because Futures uses a slightly different Controller type.

I'm not sure of the specifics but I encountered the same issue. Its either a futures Controller vs a MVC 2 Controller or MVC 1 Controller vs a MVC 2 controller.

See if fully qualifying the type name helps.

纵性 2024-10-03 07:34:51

下面怎么样:

[HttpPost]
public ActionResult Register()
{
    return this.RedirectToAction<AccountController>(x => x.AccountCreated());
}

RedirectToActionMicrosoft.Web.Mvc.ControllerExtensions 中定义的 Controller 类的扩展方法( ASP.NET MVC 期货)。

现在单元测试变得更加容易。您甚至不需要模拟上下文:

// arrange
var controller = new AccountController();

// act
var actual = controller.Register();

如果您使用优秀的 MvcContrib.TestHelper 我强烈推荐您,单元测试的断言部分可能如下所示:

// assert
actual
    .AssertActionRedirect()
    .ToAction<AccountController>(x => x.AccountCreated());

How about the following:

[HttpPost]
public ActionResult Register()
{
    return this.RedirectToAction<AccountController>(x => x.AccountCreated());
}

RedirectToAction<T> is an extension method to the Controller class defined in Microsoft.Web.Mvc.ControllerExtensions (part of ASP.NET MVC futures).

Now it's much easier to unit test. You don't even need to mock the context:

// arrange
var controller = new AccountController();

// act
var actual = controller.Register();

And if you use the excellent MvcContrib.TestHelper which I would strongly recommend you, the assert part of your unit test could look like this:

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