代码之家  ›  专栏  ›  技术社区  ›  Nik

测试ASP.NET MVC应用程序时,Microsoft.Web.MVC.LinkBuilder.BuildUrlFromExpression失败

  •  2
  • Nik  · 技术社区  · 14 年前

    所以我尝试对控制器方法进行单元测试。我正在使用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:

    方法Microsoft.Web.MVC.LinkBuilder.BuildUrlFromExpression:类型参数“tcontroller”违反类型参数“tcontroller”的约束。

    现在显然,accountcontroller是tcontroller类型,否则它在不进行单元测试时将无法工作。它继承了我的basecontroller,它继承了常规控制器。

    我觉得这个错误是一个红鲱鱼,由于嘲笑-有什么想法为什么?

    多谢。

    2 回复  |  直到 14 年前
        1
  •  2
  •   John Farrell    14 年前

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

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

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

        2
  •  1
  •   Darin Dimitrov    14 年前

    以下几点如何?

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

    RedirectToAction<T> 是的扩展方法 Controller 在中定义的类 Microsoft.Web.Mvc.ControllerExtensions (ASP.NET MVC Futures的一部分)。

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

    // arrange
    var controller = new AccountController();
    
    // act
    var actual = controller.Register();
    

    如果你使用优秀的 MvcContrib.TestHelper 我强烈建议您,单元测试的断言部分如下所示:

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