2012-12-13 7 views
7

In einem Versuch, meine Komponententests zu trocknen, versuche ich AutoFixture als ein IoC-Container zu verwenden, um mein System unter Test (SUT) zu instanziieren, die in diesem speziellen Fall ASP.NET MVC Controller s sind. Daher möchte ich AutoFixture anpassen, um Controller ohne automatische Eigenschaften zu erstellen.Wie wende ich AutoFixture-Anpassungen an alles an, das von einer Basisklasse erbt?

Ich habe versucht, eine Anpassung für ControllerBase hinzuzufügen, aber es scheint nicht für Unterklassen von ControllerBase zu arbeiten.

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

Hier ist ein Beispiel für den Test, den ich will schreiben können:

[Theory, AutoFixtureData] 
    public void ControllerTest(AccountController controller) { 
     Assert.Equal(default(UrlHelper), controller.Url); 
    } 

Natürlich funktioniert es, wenn ich manuell für jeden spezifischen Controller in meinem Projekt eine Anpassung hinzufügen, aber wer will TU das? Gibt es einen besseren Weg?

+1

Ich benutze http://stackoverflow.com/a/11657881/11635 –

Antwort

7

Die folgende Anpassung gibt den obigen Test, und tut, was Sie scheinen

public class MvcCostumization : ICustomization 
{ 
    public void Customize(IFixture fixture) 
    { 
     fixture.Customizations.Add(
      new FilteringSpecimenBuilder(
       new MethodInvoker(new ModestConstructorQuery()), 
       new ControllerSpecification())); 
    } 

    private class ControllerSpecification : IRequestSpecification 
    { 
     public bool IsSatisfiedBy(object request) 
     { 
      var t = request as Type; 
      if (t == null) 
       return false; 

      return typeof(ControllerBase).IsAssignableFrom(t); 
     } 
    } 
} 

jedoch zu fragen, dass alle Eigenschaften aller MVC-Controller deaktiviert, einschließlich User, HttpContext, ModelState, Request, Response, usw. Sie könnten diese in Unit-Tests benötigen, also sind Sie sicher, dass Sie das tun wollen?

Ich bin die erste Person, die zustimmt, dass die MVC Controller Basisklasse eine große SRP-Verletzung ist, aber es ist eine Klasse, die uns gegeben ist, also können wir nichts tun, außer zu versuchen, das Beste daraus zu machen .

Normalerweise müssen Sie nur ein wenig drehen, damit AutoFixture die meisten Eigenschaften automatisch ausfüllt.

In MVC 3 Projekten, dies kombiniert mit den AutoMoq extension, reicht aus, um Controller-Instanzen zu erstellen:

fixture.Customize<ModelBindingContext>(c => c 
    .Without(x => x.Model) 
    .Without(x => x.ModelType)); 
fixture.Inject(CultureInfo.CurrentCulture); 
+2

Danke für den Rat. Ich benutze MVC4 und musste auch 'fixture.Customize hinzufügen (c => c.Without (x => x.DisplayMode));' –

Verwandte Themen