2008-10-27 16 views
10

J'essaye de simuler HttpContext afin que je puisse tester l'unité Request.IsAuthenicated de mon contrôleur. J'utilise le blog code that I found at Scott Hanselman's pour simuler HttpContext en utilisant rhino.mocks. donc j'avoir cette pièce de test unitaire:Mocking HttpContext ne fonctionne pas

PostsController postsController = new PostsController(postDL); 
mocks.SetFakeControllerContext(postsController); 
Expect.Call(postsController.Request.IsAuthenticated).Return(true); 

Dans mon action du contrôleur, j'ai quelque chose comme if(Request.IsAuthenticated).... lorsque je tente de lancer le test unitaire, le test échoue lancer une exception nulle, et lorsque je tente de déboguer le test unitaire, je vois que le HttpContext n'est jamais assigné au contrôleur. des idées?

Répondre

0

Maintenant, pour la divulgation, je dois encore me salir les mains avec la plupart des choses que vous travaillez avec, cependant:

Si vous voulez se moquer de la IsAuthenticated, pourquoi ne pas simplement créer une classe statique pour revenir un bool qui peut être manipulé par votre code de test?

C'est un peu rond rugueux les bords, mais nous espérons que vous avez l'idée:

interface IAuthenticationChecker 
{ 
    bool IsAuthenticated { get; } 
} 

public class MockAuthenticationChecker : IAuthenticationChecker 
{ 
    static bool _authenticated = false; 

    public static void SetAuthenticated(bool value) 
    { 
     _authenticated = value; 
    } 
    #region IAuthenticationChecker Members 

    public bool IsAuthenticated 
    { 
     get { return _authenticated; } 
    } 

    #endregion 
} 

public class RequestAuthenticationChecker : IAuthenticationChecker 
{ 

    #region IAuthenticationChecker Members 

    public bool IsAuthenticated 
    { 
     get { 
      if (HttpContext.Current == null) 
       throw new ApplicationException(
        "Unable to Retrieve IsAuthenticated for Request becuse there is no current HttpContext."); 

      return HttpContext.Current.Request.IsAuthenticated; 
     } 
    } 

    #endregion 
} 

Vous pouvez ensuite utiliser une référence à au niveau de l'application, oui cela signifie que vous devez ajouter une référence à l'application niveau, et vous devez utiliser un ref différent plutôt que Request, mais vous obtenez également un contrôle complet sur l'authentification pour les tests :)

FYI - cela est totalement ouvert à être soufflé, je l'ai jeté ensemble dans environ une minute :)

8

Cela devrait fonctionner:

PostsController postsController = new PostsController(postDL); 
var context = mocks.Stub<HttpContextBase>(); 
var request = mocks.Stub<HttpRequestBase>(); 
SetupResult.For(request.IsAuthenticated).Return(true); 
SetupResult.For(context.Request).Return(request);  
postsController.ControllerContext = new ControllerContext(context, new RouteData(), postsController); 
0

Voici une façon simple de truquer le contexte, trouvé il de Jeff's blog:

 TextWriter tw = new StringWriter(); 
     HttpWorkerRequest wr = new SimpleWorkerRequest("/webapp", "c:\\inetpub\\wwwroot\\webapp\\", "default.aspx", "", tw); 
     HttpContext.Current = new HttpContext(wr);