43 votes

ASP/NET MVC : Contrôleurs de test avec sessions ? Mocking ?

J'ai lu certaines des réponses ici concernant le test des vues et des contrôleurs, et le mocking, mais je n'arrive toujours pas à comprendre comment tester un contrôleur ASP.NET MVC qui lit et définit les valeurs de session (ou toute autre variable basée sur le contexte). Comment fournir un contexte (de session) à mes méthodes de test ? Le mocking est-il la solution ? Quelqu'un a des exemples ? En gros, j'aimerais simuler une session avant d'appeler la méthode du contrôleur et faire en sorte que le contrôleur utilise cette session. Des idées ?

44voto

David P Points 2430

Consultez le billet de Stephen Walther sur la simulation du contexte du contrôleur :

Conseil ASP.NET MVC n° 12 - Simuler le contexte du contrôleur

[TestMethod]
public void TestSessionState()
{
    // Create controller
    var controller = new HomeController();

    // Create fake Controller Context
    var sessionItems = new SessionStateItemCollection();
    sessionItems["item1"] = "wow!";
    controller.ControllerContext = new FakeControllerContext(controller, sessionItems);
    var result = controller.TestSession() as ViewResult;

    // Assert
    Assert.AreEqual("wow!", result.ViewData["item1"]);

    // Assert
    Assert.AreEqual("cool!", controller.HttpContext.Session["item2"]);
}

13voto

chadmyers Points 3010

Le cadre ASP.NET MVC n'est pas très convivial pour les simulateurs (ou plutôt, il nécessite trop de configuration pour simuler correctement, et cause trop de frictions lors des tests, IMHO) en raison de son utilisation de classes de base abstraites au lieu d'interfaces. Nous avons eu de la chance en écrivant des abstractions pour le stockage par requête et par session. Nous gardons ces abstractions très légères et ensuite nos contrôleurs dépendent de ces abstractions pour le stockage par requête ou par session.

Par exemple, voici comment nous gérons les formulaires d'authentification. Nous avons un ISecurityContext :

public interface ISecurityContext
{
    bool IsAuthenticated { get; }
    IIdentity CurrentIdentity { get; }
    IPrincipal CurrentUser { get; set; }
}

Avec une implémentation concrète comme :

public class SecurityContext : ISecurityContext
{
    private readonly HttpContext _context;

    public SecurityContext()
    {
        _context = HttpContext.Current;
    }

    public bool IsAuthenticated
    {
        get { return _context.Request.IsAuthenticated; }
    }

    public IIdentity CurrentIdentity
    {
        get { return _context.User.Identity; }
    }

    public IPrincipal CurrentUser
    {
        get { return _context.User; }
        set { _context.User = value; }
    }
}

10voto

thedeeno Points 12553

Avec MVC RC 1, le ControllerContext enveloppe le HttpContext et l'expose comme une propriété. Cela rend le mocking beaucoup plus facile. Pour simuler une variable de session avec Moq, procédez comme suit :

var controller = new HomeController();
var context = MockRepository.GenerateStub<ControllerContext>();
context.Expect(x => x.HttpContext.Session["MyKey"]).Return("MyValue");
controller.ControllerContext = context;

Voir Le message de Scott Gu pour plus de détails.

5voto

Korbin Points 752

J'ai trouvé que la moquerie était assez facile. Voici un exemple d'adaptation de la base httpContext (qui contient les objets requête, session et réponse) à l'aide de moq.

[TestMethod]
        public void HowTo_CheckSession_With_TennisApp() {
            var request = new Mock<HttpRequestBase>();
            request.Expect(r => r.HttpMethod).Returns("GET");     

            var httpContext = new Mock<HttpContextBase>();
            var session = new Mock<HttpSessionStateBase>();

            httpContext.Expect(c => c.Request).Returns(request.Object);
            httpContext.Expect(c => c.Session).Returns(session.Object);

            session.Expect(c => c.Add("test", "something here"));            

            var playerController = new NewPlayerSignupController();
            memberController.ControllerContext = new ControllerContext(new RequestContext(httpContext.Object, new RouteData()), playerController);          

            session.VerifyAll(); // function is trying to add the desired item to the session in the constructor
            //TODO: Add Assertions   
        }

J'espère que cela vous aidera.

2voto

Nick DeVore Points 4424

Scott Hanselman a publié un article sur comment créer un téléchargement de fichiers quickapp avec MVC et discute de la moquerie et aborde spécifiquement "Comment moquer les choses qui ne sont pas mock friendly".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X