Question

Existe-t-il un moyen de (unité) de tester mes propres HtmlHelpers? Dans le cas où je voudrais avoir un contrôle personnalisé (rendu par HtmlHelper) et que je connais les exigences pour ce contrôle, comment pourrais-je écrire des tests en premier, puis écrire du code? Y a-t-il un moyen spécifique (agréable) de le faire?

Vaut-il la peine?

Était-ce utile?

La solution

Le problème principal est que vous devez vous moquer de HtmlHelper car vous utilisez peut-être des méthodes de l’assistant pour obtenir des itinéraires ou des valeurs, ou vous renvoyez le résultat d’une autre méthode d’extension. La classe HtmlHelper a beaucoup de propriétés et certaines d’entre elles assez complexes comme le ViewContext ou le contrôleur actuel.

Ce message de Ben Hart explique comment créer une telle maquette avec Moq. Peut être facilement traduit dans un autre cadre factice.

Voici ma version de Rhino Mocks adaptée aux modifications apportées au framework MVC. Ce n'est pas complètement testé, mais ça marche pour moi, mais ne vous attendez pas à des résultats parfaits:

    public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData)
    {
        var mocks = new MockRepository();

        var cc = mocks.DynamicMock<ControllerContext>(
            mocks.DynamicMock<HttpContextBase>(),
            new RouteData(),
            mocks.DynamicMock<ControllerBase>());

        var mockViewContext = mocks.DynamicMock<ViewContext>(
            cc,
            mocks.DynamicMock<IView>(),
            viewData,
            new TempDataDictionary());

        var mockViewDataContainer = mocks.DynamicMock<IViewDataContainer>();

        mockViewDataContainer.Expect(v => v.ViewData).Return(viewData);

        return new HtmlHelper(mockViewContext, mockViewDataContainer);
    }

Autres conseils

Si quelqu'un cherche comment créer HtmlHelper<T> (c'est ce que je recherchais), voici une implémentation qui pourrait aider - mon type est une classe nommée Model:

public static HtmlHelper<Model> CreateHtmlHelper()
{
    ViewDataDictionary vd = new ViewDataDictionary(new Model());

    var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object,
                                                  new RouteData(),
                                                  new Mock<ControllerBase>().Object);

    var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object);

    var mockViewDataContainer = new Mock<IViewDataContainer>();
    mockViewDataContainer.Setup(v => v.ViewData).Returns(vd);

    return new HtmlHelper<Model>(viewContext, mockViewDataContainer.Object);
}

Ou une implémentation plus générique:

    public HtmlHelper<T> CreateHtmlHelper<T>() where T : new()
    {
        var vd = new ViewDataDictionary(new T());

        var controllerContext = new ControllerContext(new Mock<HttpContextBase>().Object,
                                                      new RouteData(),
                                                      new Mock<ControllerBase>().Object);

        var viewContext = new ViewContext(controllerContext, new Mock<IView>().Object, vd, new TempDataDictionary(), new Mock<TextWriter>().Object);

        var mockViewDataContainer = new Mock<IViewDataContainer>();
        mockViewDataContainer.Setup(v => v.ViewData).Returns(vd);

        return new HtmlHelper<T>(viewContext, mockViewDataContainer.Object);
    }

Je crée un assistant personnalisé, et c'est le code que j'utilise pour simuler httphelper avec Moq et ASP MVC 2. Je passe également en paramètre un simulacre de HttpRequestBase. Vous pouvez supprimer cela si vous n'en avez pas besoin

public static HtmlHelper CreateHtmlHelper(ViewDataDictionary viewData, Mock requestMock)
        {
            var contextBaseMock = new Mock();
            contextBaseMock.SetupGet(cb => cb.Request).Returns(requestMock.Object);

            var cc = new ControllerContext(contextBaseMock.Object,
                                            new RouteData(),
                                            new Mock().Object);
            var vctx = new ViewContext(
                cc,
                new Mock().Object,
                viewData,
                new TempDataDictionary(),
                new HtmlTextWriter(new StreamWriter(new MemoryStream())));

            var mockViewDataContainer = new Mock();

            mockViewDataContainer.SetupGet(v => v.ViewData).Returns(viewData);

            return new HtmlHelper(vctx, mockViewDataContainer.Object);
        }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top