2012-08-14 16 views
6

Soy nuevo en AutoFixture, así que no sé si la siguiente idea tendrá sentido o será razonable. Tengo una aplicación que estoy a cargo de la prueba de integración , y hace un uso intensivo de Castle Windsor. Para simplificar la administración de dependencias y hacer que mis pruebas se parezcan más al código de la aplicación, he estado construyendo el contenedor Windsor en mi método de inicialización de prueba y en el contenedor que lo usa. Resuelva para crear una instancia del código que estoy probando. Me gustaría alejarme de ese enfoque, ya que ha limitado mi flexibilidad en ciertas situaciones.Técnica para usar AutoFixture para la integración prueba una aplicación usando Castle Windsor

Lo que me gustaría hacer es tener pruebas que buscan algo como esto:

[Theory] 
[Dependency] 
public void TestWithDependencies(IThing thing) 
{ 
    thing.Hello(); 
} 

para que esto suceda, no puedo hacer lo siguiente:

public sealed class DependencyAttribute : AutoDataAttribute 
{ 
    public DependencyAttribute() 
     : base(new Fixture().Customize(new WindsorCustomization())) 
    { 
    } 
} 

public class WindsorCustomization : ICustomization 
{ 
    public WindsorCustomization() 
    { 
     // build container here using SUT installers 
    } 

    public void Customize(IFixture fixture) 
    { 
     fixture.Inject<IThing>(new Thing()); 
    } 
} 

Hacer esto funciona, pero lo que me gustaría evitar es copiar cada interfaz al mapeo de implementación desde el contenedor de Windsor a la base de ajuste automático.

+0

Welp! Solo eché un vistazo al código de AutoMoq y vi exactamente cómo hacer lo que quiero hacer. Puedo publicar el código en una respuesta si alguien está interesado. – thebeekeeper

+0

Sí, está muy cerca de cómo funciona AutoMoq también :) –

Respuesta

6

Usted debe ser capaz de hacer algo como esto:

public class WindsorCustomization : ICustomization 
{ 
    private readonly IWindsorContainer container; 

    public WindsorCustomization() 
    { 
     // build this.container here using SUT installers 
    } 

    public void Customize(IFixture fixture) 
    { 
     fixture.Customizations.Add(new WindsorAdapter(this.container)); 
    } 
} 

public WindsorAdapter : ISpecimenBuilder 
{ 
    private readonly IWindsorContainer container; 

    public WindsorAdapter(IWindsorContainer container) 
    { 
     this.container = container; 
    } 

    public object Create(object request, ISpecimenContext context) 
    { 
     var t = request as Type; 
     if (t == null || !this.container.Kernel.HasComponent(t)) 
      return new NoSpecimen(request); 

     return this.container.Resolve(t);     
    } 
} 

El WindsorAdapter se encuentra en la colección Customizations, que es bastante temprano en el árbol de la responsabilidad de AutoFixture, por lo que tiene la oportunidad de manejar todos (o la mayoría) solicitudes entrantes. Si la solicitud es una instancia de Tipo y WindsorContainer tiene un componente para ese tipo, el adaptador delega el trabajo de resolver el tipo en el contenedor.

De lo contrario, devuelve una instancia de NoSpecimen, que es básicamente la manera de AutoFixture de indicar que este ISpecimenBuilder particular no pudo manejar la solicitud. Algún otro componente en el Árbol de Responsabilidad de Ajuste Automático tiene la oportunidad de manejar la solicitud.

+1

Sí, eso es exactamente lo que hice. La parte más emocionante de esto es que dado que estoy probando un código que está solo 1/3 implementado, debería poder usar AutoMoq para sustituir el código que no existe y aún así probar el código que sí existe. Gran biblioteca! – thebeekeeper

+0

Sí, solo necesita asegurarse de que AutoMoqCustomization sea el último/posterior: http://blog.ploeh.dk/2012/07/31/TheOrderOfAutoFixtureCustomizationsMatter.aspx –

Cuestiones relacionadas