unitarias software pruebas niveles las integracion herramientas desventajas unit-testing castle-windsor

unit-testing - software - pruebas unitarias laravel



En Castle Windsor 3, anular un registro de componente existente en una prueba de unidad (2)

Estoy tratando de usar Castle Windsor en mis pruebas automatizadas de la siguiente manera:

En cada prueba:

  • La función Setup() crea un contenedor Windsor, registrando implementaciones predeterminadas de cada componente
  • La función de Test accede a los componentes a través del método IWindsorContainer.Resolve<T> y prueba su comportamiento
  • La función TearDown() elimina el contenedor de Windsor (y cualquier componente creado)

Por ejemplo, podría tener 15 pruebas que accedan a componentes, lo que indirectamente resulta en la creación de un componente IMediaPlayerProxyFactory . La función SetUp registra una implementación suficientemente buena IMediaPlayerProxyFactory , por lo que no tengo la carga de mantenimiento de registrar esto en cada una de las 15 pruebas.

Sin embargo, ahora estoy escribiendo una prueba Test_MediaPlayerProxyFactoryThrowsException , confirmando que mi sistema maneja con elegancia un error del componente IMediaPlayerProxyFactory . En el método de prueba, he creado mi implementación simulada especial, y ahora quiero insertarla en el marco:

this.WindsorContainer.Register( Component.For<IMediaPlayerProxyFactory>() .Instance(mockMediaPlayerProxyFactory) );

Pero Windsor lanza una Castle.MicroKernel.ComponentRegistrationException , con el mensaje "Ya existe un componente con ese nombre".

¿Hay alguna manera de hacer que mockMediaPlayerProxyFactory sea ​​la instancia predeterminada para IMediaPlayerProxyFactory , descartando el componente que ya está registrado?

Según la documentation , Castle Windsor 3 permite anulaciones de registro, pero solo pude encontrar un ejemplo:

Container.Register( Classes.FromThisAssembly() .BasedOn<IEmptyService>() .WithService.Base() .ConfigureFor<EmptyServiceA>(c => c.IsDefault()));

ConfigureFor es un método de la clase BasedOnDescriptor . En mi caso no estoy usando el FromDescriptor o BasedOnDescriptor .


Hay dos cosas que debes hacer para crear una instancia de reemplazo:

  1. Asígnele un nombre único
  2. Llame al método IsDefault

Así que para que el ejemplo funcione:

this.WindsorContainer.Register( Component.For<IMediaPlayerProxyFactory>() .Instance(mockMediaPlayerProxyFactory) .IsDefault() .Named("OverridingFactory") );

Debido a que planeo usar este patrón de reemplazo en muchas pruebas, he creado mi propio método de extensión:

public static class TestWindsorExtensions { public static ComponentRegistration<T> OverridesExistingRegistration<T>(this ComponentRegistration<T> componentRegistration) where T : class { return componentRegistration .Named(Guid.NewGuid().ToString()) .IsDefault(); } }

Ahora el ejemplo se puede simplificar para:

this.WindsorContainer.Register( Component.For<IMediaPlayerProxyFactory>() .Instance(mockMediaPlayerProxyFactory) .OverridesExistingRegistration() ); Edición posterior

La versión 3.1 introduce el método IsFallback . Si registro todos mis componentes iniciales con IsFallback , cualquier nuevo registro anulará automáticamente estos registros iniciales. Hubiera seguido ese camino si la funcionalidad estuviera disponible en ese momento.

https://github.com/castleproject/Windsor/blob/master/docs/whats-new-3.1.md#fallback-components


No reutilice su envase a través de pruebas. En su lugar, TearDown() en null en TearDown() y TearDown() para cada prueba real.