2010-10-08 11 views
2

J'essaie donc d'effectuer une unité de test d'une méthode de contrôleur. J'utilise MSTest dans VS 2010, et Moq 3.1Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression échouant lors du test de l'application Asp.net MVC

Méthode d'essai:

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

Ma méthode de commande:

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

La méthode du contrôleur fonctionne très bien lorsqu'ils ne sont pas des tests unitaires.

Lorsque moqueur et appeler de cette façon, je reçois un System.Security.VerificationException sur cette dernière ligne:

Méthode Microsoft.Web.Mvc.LinkBuilder.BuildUrlFromExpression: argument de type « TController » constitue une violation de la contrainte de type paramètre 'TController'.

Maintenant, il est clair que AccountController est de type TController, sinon il ne fonctionnerait pas s'il n'y a pas de test unitaire. Il hérite de mon BaseController, qui hérite du contrôleur régulier.

J'ai l'impression que cette erreur est un rouge-hareng, à cause des moqueries - des idées pourquoi?

Merci beaucoup.

Répondre

2

Ceci est dû au fait que Futures utilise un type de contrôleur légèrement différent.

Je ne suis pas sûr des détails mais j'ai rencontré le même problème. C'est soit un contrôleur à terme vs un contrôleur MVC 2 ou un contrôleur MVC 1 vs un contrôleur MVC 2.

Voir si la qualification complète du nom de type aide.

+0

Il a fini par être exactement cela - j'ai eu un avenir v1 dll référencé dans mon projet de test, mais v2 dans l'application réelle. Merci beaucoup. – Nik

1

Comment les éléments suivants:

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

RedirectToAction<T> est une méthode d'extension de la classe définie dans la ControllerMicrosoft.Web.Mvc.ControllerExtensions (partie du terme ASP.NET MVC).

Maintenant, il est beaucoup plus facile de faire un test unitaire. Vous ne devez même pas se moquer du contexte:

// arrange 
var controller = new AccountController(); 

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

Et si vous utilisez l'excellent MvcContrib.TestHelper que je ne saurais trop vous recommander, la partie assert de votre test unitaire pourrait ressembler à ceci:

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

Merci à une pile pour la tête sur les trucs Contrib tester et la méthode d'extension - c'est excellent. – Nik