2010-08-13 2 views
2

J'ai vu comment Fake l'objet SessionState dans MVC en utilisant Scott Hanselmans MvcMockHelpers, mais j'ai affaire à un problème distinct. Ce que j'aime faire est de créer un wrapper autour de l'objet Session pour rendre les objets un peu plus accessibles et fortement typés plutôt que d'utiliser des touches partout. Voici essentiellement ce qu'il fait:Mocking un wrapper de session dans MVC2

public class SessionVars 
{ 
    public SessionVars() 
    {} 

    public string CheckoutEmail 
    { 
     get { return Session[checkoutEmailKey] as string; } 
     set { Session[checkoutEmailKey] = value; } 
    } 
} 

Alors que je peux le faire dans mes contrôleurs et points de vue:

SessionVars s = new SessionVars(); 
s.CheckoutEmail = "[email protected]"; 

Maintenant, le problème vient quand je veux écrire des tests unitaires, cette classe est étroitement couplé avec le HttpSessionState. Ce que je ne peux pas comprendre, c'est quelle est la bonne classe à accepter/passer afin que je puisse passer une FakeHttpSession dans la classe SessionVars. J'ai essayé beaucoup de choses avec ceci, et ceci (ci-dessous) compilera, mais il ne peut pas transformer le HttpSessionState en IDictionary. J'ai essayé ICollection, HttpSessionStateBase.

public class SessionVars 
{ 
    public SessionVars() : this(HttpContext.Current.Session) { } 
    public SessionVars(ICollection session) 
    { 
     Session = (IDictionary<string, object>)session; 
    } 

    public IDictionary<string, object> Session 
    { 
     get; 
     private set; 
    } 

    public string CheckoutEmail 
    { 
     get { return Session[checkoutEmailKey] as string; } 
     set { Session[checkoutEmailKey] = value; } 
    } 

    public Order Order 
    { 
     get { return Session[orderKey] as Order; } 
     set { Session[orderKey] = value; } 
    } 
} 

Il me manque quelque chose de grand ici. J'ai l'impression que c'est possible et que je devrais même être si loin.

Répondre

1

Avez-vous essayé d'utiliser le HttpSessionStateWrapper de System.Web.Abstractions?

il peut être aussi facile que:

new HttpSessionStateWrapper(Session) 

Vous pouvez railler HttpSessionStateWrapper.

+0

Pouvez-vous donner un exemple? Je peux me moquer de la session dans un test, je le comprends. Ce que je ne comprends pas, c'est comment configurer ma classe SessionVars pour que je puisse injecter une version mockée. Je ne savais pas que cette classe existait, donc maintenant je suis encore plus confus quant à savoir si utiliser le HttpSessionStateBase, IHttpSessionState ou HttpSessionStateWrapper. Quel est le type de la version abstraite de l'objet Session dans ma classe SessionVars? – MaseBase

+0

En fait, je pense que je comprends ce que vous voulez dire. C'est ce qui me manquait, le fait que je ne puisse pas passer de HttpSessionState à HttpSessionStateBase sans utiliser la classe HttpSessionStateWrapper que vous avez mentionnée ici. – MaseBase

+0

Cela n'a pas fonctionné pour moi, en utilisant MVC5 et Moq. Impossible de se moquer de HttpSessionStateWrapper car il nécessite un objet SessionState dans le constructeur. Mais, vous pouvez simuler HttpSessionStateBase qui est le parent de la classe abstraite de HttpSessionStateWrapper. Comme suit: 'var sessionStateMock = nouveau Mock ();' 'sessionStateMock.Setup (x => x [" clé "]). Renvoie (" Valeur ");' – Jansky

1

Ma mise en œuvre d'aide de la session (inspiration):

http://github.com/Necroskillz/NecroNetToolkit/blob/master/Source/NecroNet.Toolkit/SessionData.cs

http://github.com/Necroskillz/NecroNetToolkit/blob/master/Source/NecroNet.Toolkit/ILocalDataProvider.cs

En outre, vous pouvez soit utiliser HttpSessionState béton dans les tests unitaires (voici comment créer: http://www.necronet.org/archive/2010/07/28/unit-testing-code-that-uses-httpcontext-current-session.aspx), ou vous pouvez utiliser HttpSessionStateBase, mais alors vous devrez initialiser votre assistant avec l'objet approprié fourni par MVC (quelque chose comme ControllerContext.HttpContext.Session).