Question

La question initiale est:Test d'unité d'une aide HTML avec Autofixture

Je ne suis pas sûr de rouvrir la question initiale; Cependant, depuis que j'ai marqué la question initiale comme résolu, j'ai décidé d'en créer une nouvelle. Excuses si je faisais ça mal.

J'utilisais l'approche suggérée de Mark mais je me suis retrouvé coincé en utilisant le gel.

Vous trouverez ci-dessous le code source complet… Class sous test:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace MvcDemo2.Helpers
{
      public static class Keys
      {
          public static readonly string SomeKey = "SomeKey";
      }

      public static class SampleHelpers
      {
          public static MvcHtmlString SampleTable(this HtmlHelper helper, 
            SampleModel model, IDictionary<string, object> htmlAttributes)
          {
                if (helper == null)
                {
                    throw new ArgumentNullException("helper");
                }

                if (model == null)
                {
                    throw new ArgumentNullException("model");
                }

                TagBuilder tagBuilder = new TagBuilder("table");
                tagBuilder.MergeAttributes(htmlAttributes);                               
                tagBuilder.GenerateId(helper.ViewContext.
                                 HttpContext.Items[Keys.SomeKey].ToString());
                return MvcHtmlString.Create(
                         tagBuilder.ToString(TagRenderMode.Normal));
            }
      }
  }


  public class SampleModel
  {
  }
}

Le test unitaire consiste à s'assurer que le HTML est renvoyé comme prévu pour la touche spécifiée dans HTTPContext

public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()

J'ai configuré le luminaire comme ci-dessous

var fixture = new Fixture().Customize(new AutoMoqCustomization());

Ensuite, le gel sur ViewContext:

var vc = fixture.Freeze<ViewContext>();

J'obtiens l'exception ci-dessous:

Erreur 1 Test 'mvcdemo2.tests.controllers.samplehelperstestsautofixture.sampletablehtmlhelper_whenkeyexistwithinhttpcontext_returnsexpecyhtml' a échoué: system.reflection.targetinvocationException: une exception a été lancée par la cible d'une invocation. ---- System.NoTIMPLEMENTEDException: la méthode ou l'opération n'est pas implémentée. à System.RuntimeMethodHandle._InvokeMethodFast (Méthode IruntimeMethodInfo, cible d'objet, objet [] Arguments, SignaturSruct & Sig, méthodattributes MethoodAtButes, RuntimeType Typeowner , RuntimeType TypeOrner) sur System.Reflection.RuntimeMethodInfo.invoke (Object Obj, BindingFlags Invokeattr, Binder Binder, Object [] Paramètres, CultureInfo Culture, Boolean SkipVisibilityCheck , Objet [] Paramètres, culture CultureInfo)
at system.reflection.runtimepropertyinfo.setValue (objet obj, valeur d'objet, lisingflags invokeattr, liant liant, objet [] index, culture de culture) à System.Reflection.runtimePropertyInfo.SetValue (objet obj, valeur d'objet, objet [] index à la Ploeh.Autofixture.kernel.AutopropertiesCommand1.Execute(T specimen, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.Postprocessor1.Create (demande d'objet, contexte iSpecimenContext) sur ploeh.autofixture.kernel.compositespecimenbuilder. <> C__displayclass6.b__1 (ispecimenbuilder b) sur System.linq.enumerable.WhereselectListIterator2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoVeNext ()
à System.Linq.Enumable.d__a51.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 source) sur plaeh.autofixture.kernel.compositespecimenbuilder.create (demande d'objet, contexte iSpemenContext) sur ploeh.autofixture.kernel.recursionguard.create (objet request, iSpecimenContex ) sur ploeh.autofixture.kernel.seedigningRelay.create (demande d'objet, iSpecimenContext Context) sur ploeh.autofixture.kernel.2.MoveNext()
at System.Linq.Enumerable.WhereSelectEnumerableIterator
2.MoVeNext ()
à System.Linq.Enumable.d__a51.MoveNext()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable
1 source) sur plaeh.autofixture.kernel.compositespecimenbuilder.create (demande d'objet, contexte iSpecimenContext) sur plaeh.autofixture.kernel.postprocessor1.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.<>c__DisplayClass6.<Create>b__1(ISpecimenBuilder b) at System.Linq.Enumerable.WhereSelectListIterator2.MoVeNext ()
à System.Linq.Enumable.WhereselelecTumeRableterator2.MoveNext()
at System.Linq.Enumerable.<DefaultIfEmptyIterator>d__a5
1.MoVeNext ()
at system.linq.enumable.firstordefault [tsource] (ienumerable1 source) at Ploeh.AutoFixture.Kernel.CompositeSpecimenBuilder.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.RecursionGuard.Create(Object request, ISpecimenContext context) at Ploeh.AutoFixture.Kernel.SpecimenContext.Resolve(Object request) at Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous[T](ISpecimenContext context, T seed) at Ploeh.AutoFixture.SpecimenFactory.CreateAnonymous[T](ISpecimenBuilderComposer composer, T seed) at Ploeh.AutoFixture.FixtureFreezer.Freeze[T](IFixture fixture, T seed)
at MvcDemo2.Tests.Controllers.SampleHelpersTestsAutoFixture.SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml() in C:\Users\...:line 78 ----- Inner Stack Trace ----- at System.Web.HttpContextBase.get_Items() at System.Web.Mvc.ViewContext.ScopeCache.Get(IDictionary
2 Scope, httpContextBase httpContext) sur System.web.mvc.ViewContext.SetClientValidationNabled (Boolean active

Il semble que cela échoue lorsqu'il essaie de définir la valeur de la propriété ViewContext.SetClientValidationDabled.

Je suis coincé là-dessus. Toutes les pensées appréciées.

Était-ce utile?

La solution

Eh bien, si vous considérez la trace de pile intérieure, vous remarquerez que l'exception est lancée par HttpContextBase.Items. Si vous deviez examiner l'implémentation à l'aide d'un outil de réflexion, vous constateriez que cette méthode virtuelle lance une notation NOTIMPLEDEDException - parlez d'une violation de Pola. Une grande partie des abstractions Web dans le BCL fait exactement cela, ce qui est vraiment très douloureux à gérer.

Je ne suis pas sûr que cela vous aidera plus loin, mais vous pouvez dépasser ce problème particulier en désactivant les autoproperties pour la classe ViewContext comme ceci:

fixture.Customize<ViewContext>(c => c.OmitAutoProperties());

Autres conseils

Merci Mark. Je trouve que l'autofixture est très utile, mais lorsque je teste MVC, je trouve un peu plus difficile pour appliquer l'API. C'est probablement parce que je suis encore nouveau dans l'API.

Avec….

  fixture.Customize<ViewContext>(c => c.OmitAutoProperties());
  var vc = fixture.Freeze<ViewContext>();

Ce qui précède fonctionne bien, mais comme vous le soupçonnez, il échoue à nouveau lorsque j'essaie d'ajouter des éléments à

  vc.HttpContext.Items.Add(Keys.SomeKey, "foo");

Saufliion: la méthode ou l'opération n'est pas implémentée.

Le réflecteur sur httpcontextbase ...

  public virtual IDictionary Items
  {
     get
     {
         throw new NotImplementedException();
     }
  }

Donc, la seule façon de penser est de créer ma propre implémentation de HttpContextBase

    private class FakeHttpContext : HttpContextBase
    {
        private Dictionary<object, object> _items = new Dictionary<object, object>();
        public override IDictionary Items { get { return _items; } }
    }

Ensuite, ci-dessous est le bit déroutant.

   fixture.Inject<HttpContextBase>(new FakeHttpContext());
   var hc = fixture.CreateAnonymous<HttpContextBase>();

Si j'échange ces deux lignes (ce qui crée d'abord l'instance Anonymouse, puis l'injecte la fausse instance) provoque l'erreur.

AutoFixture n'a pas été en mesure de créer une instance à partir de System.Web.httpContextBase, très probablement parce qu'elle n'a pas de constructeur public.

Jusqu'à présent, je peux proposer un test comme celui-ci ...

    public void SampleTableHtmlHelper_WhenKeyExistWithinHttpContext_ReturnsExpectedHtml()
    {
        //Arrange
        var fixture = new Fixture(); 
        fixture.Customize<ViewContext>(c => c.OmitAutoProperties());
        var vc = fixture.Freeze<ViewContext>();
        fixture.Inject<HttpContextBase>(new FakeHttpContext());
        var hc = fixture.CreateAnonymous<HttpContextBase>();

        vc.HttpContext = hc;
        vc.HttpContext.Items.Add(Keys.SomeKey, "foo");

        var htmlHelper = fixture.CreateAnonymous<HtmlHelper>();
        var sampleModel = fixture.CreateAnonymous<SampleModel>();

        //Act
        var result = SampleHelpers.SampleTable(htmlHelper, sampleModel, null).ToString();

        //Assert
        Assert.Equal("<table id=\"foo\"></table>", result);
    }

A également supprimé la nouvelle AutomoQCustanisation () car elle semble n'avoir aucun effet sur le test. Une fois que je me familiariser avec AutoFixture, je pourrais peut-être trouver une meilleure version. Merci pour l'aide.

Il semble que cela échoue lorsqu'il essaie de définir la valeur de la propriété ViewContext.SetClientValidationEnabled.

Ce problème a été résolu pour moi par cette réponse, voir comment il obtient un htmlhelper (voir aussi ici).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top