2010-10-08 27 views
2

所以我试图单元测试一个控制器方法。我在VS 2010中使用MSTest的,起订量和3.1当测试Asp.net MVC应用程序时,Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression失败

测试方法:

[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继承,它从常规Controller继承。

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

非常感谢。

回答

2

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

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

看看是否完全符合类型名称的帮助。

+0

它最终就是这样 - 我在我的测试项目中引用了期货v1 dll,但在实际应用中有v2。非常感谢。 – Nik 2010-10-09 16:23:39

1

如何执行以下操作:

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

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

现在单元测试更容易了。你甚至都不需要模拟情境:

// arrange 
var controller = new AccountController(); 

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

如果你使用优秀MvcContrib.TestHelper我强烈建议你,你的单元测试的断言部分看起来是这样的:

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

非常感谢Contrib测试人员和扩展方法的堆栈 - 非常好。 – Nik 2010-10-09 16:24:28

相关问题