0 votes

Mocking d'un objet SessionHandler client dans ASP.NET MVC pour les Unittests avec Rhino Mocks

J'utilise actuellement l'approche suivante pour créer un objet fortement typé représentant les variables de session.

public abstract class SessionController : Controller
{
    private const string SESSION_NAME = "UserSession";

    public SessionData SessionData
    {
        get
        {
            SessionData sessionData = (SessionData)Session[SESSION_NAME];

            if (sessionData != null)
            {
                return sessionData;
            }
            else
            {
                sessionData = new SessionData();
                Session[SESSION_NAME] = sessionData;

                return sessionData;
            }
        }
        set
        {
            Session[SESSION_NAME] = value;
        }
    }  
}

SessionData est un objet simple comme par exemple

[Serializable]
public class SessionData
{
    public String SessionId { get; set; }
    public Int64 UserId { get; set; }
    public String NameOfUser { get; set; }
}

Lorsque je crée un nouveau contrôleur, je le dérive du SessionController afin d'avoir un accès typiquement fort à mes SessionData. Par exemple

public CityController : SessionController
{
    [AcceptVerbs(HttpVerbs.Get)]
    public ActionResult Index()
    {
        ViewData.Model = _cityService.GetAll(SessionData.UserId);

        return View("Index");
    }
}

Je me bats donc en ce moment pour que cette approche soit couverte par un unittest. Une version abrégée de ce que j'ai essayé est le bout de phrase suivant

[SetUp]
public void SetUp()
{
    mocks = new MockRepository();
    _cityService = MockRepository.GenerateStub<ICityService>();
    _sesssionData = new SessionData { UserId = 1, SessionId = "1" };

    // First Approach
    controller = new CityController(_cityService);
    controller.Expect(p => p.SessionData).Return(_sesssionData);

    // Second Approach
    cctx = MockRepository.GenerateStub<ControllerContext>();
    cctx.Expect(p=>p.HttpContext.Session["UserSession"] as SessionData).Return(_sesssionData);
    controller.ControllerContext = cctx;
}

Quelqu'un a-t-il un conseil sur la façon de résoudre ce problème ?

0voto

Darin Dimitrov Points 528142

Si vous rendez votre propriété SessionData virtuelle, votre première approche pourrait fonctionner :

// Arrange
var mocks = new MockRepository();
var cityService = MockRepository.GenerateStub<ICityService>();
var sesssionData = new SessionData { UserId = 1, SessionId = "1" };
var controller = mocks.PartialMock<CityController>(cityService);
controller.Expect(c => c.SessionData).Return(sessionData);
controller.Replay();

// Act
controller.Index();

//Assert
...

IMO cette approche n'est pas très bonne parce que le SUT (Subject Under Test => dans ce cas CityController) est simulé avec PartialMock.

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