CodeGo.net>如何使用SimpleInjector 3单元测试装饰器注册?
作者:互联网
在这里跟进an older question.假设我的注册如下:
container.Register(typeof(IHandleCommand<>), _handlerAssemblies, Lifestyle.Transient);
container.RegisterDecorator(typeof(IHandleCommand<>),
typeof(MetricsCommandHandlerWrapper<>), Lifestyle.Singleton);
MetricsCommandHandlerWrapper的定义如下:
public class MetricsCommandHandlerWrapper<T> : IHandleCommand<T> where T: ICommand
{
private readonly ICollectMetrics _metrics;
private readonly Func<IHandleCommand<T>> _handlerFactory;
public MetricsCommandHandlerWrapper(ICollectMetrics metrics,
Func<IHandleCommand<T>> handlerFactory)
{
_metrics = metrics;
_handlerFactory = handlerFactory;
}
public async Task HandleAsync(T command)
{
// code to record metrics around command handling which eventually invokes
await _handlerFactory().HandleAsync(command).ConfigureAwait(false);
}
}
我该如何编写一个单元测试来断言实际的装饰者处理程序已在Transient生活方式中注册?
我试过组成根并检查封闭的IHandleCommand< FakeCommand>的注册.类型,该类型揭示MetricsCommandHandlerWrapper< FakeCommand>的ImplementationType.如预期的那样.在该注册上调用GetRelationships()会显示其2个依赖项ICollectMetrics和我感兴趣的2个依赖项Func< IHandleCommand< FakeCommand>>.工厂代表,已注册为Singleton.但是,对该工厂委托调用.Dependency.GetInstance()会引发异常,实例生产者返回null.
有什么方法可以断言内部装饰对象已注册为瞬态,如果是,则如何?
解决方法:
Func< T>的使用延迟了对象图的构建,并且从诊断系统的角度来看,图在该点停止.因此,不可能进行此分析.
但是,您可以选择在应用程序中进行一些小的更改以允许测试装饰器,而不是完全依赖Simple Injector的内部结构.
您可以做的是在装饰器上实现IDecorator抽象:
public interface IDecorator {
object Decoratee { get; }
}
现在,每个装饰器都可以实现此接口.对于MetricsCommandHandlerWrapper< T> ;,它可能如下所示:
public class MetricsCommandHandlerWrapper<T> : IHandleCommand<T>, IDecorator where T: ICommand
{
private readonly ICollectMetrics _metrics;
private readonly Func<IHandleCommand<T>> _handlerFactory;
public MetricsCommandHandlerWrapper(ICollectMetrics metrics,
Func<IHandleCommand<T>> handlerFactory) {
_metrics = metrics;
_handlerFactory = handlerFactory;
}
public object Decoratee { get { return _handlerFactory(); }
public async Task HandleAsync(T command) { ... }
}
在IDecorator界面的顶部,您可以定义一个简单的扩展方法:
public static IEnumerable<Type> GetDecoratorChain(this IDecorator decorator) {
while (decorator != null) {
yield return decorator.GetType();
decorator = decorator.Decoratee as IDecorator;
}
}
现在,在单元测试中,您可以解析一个处理程序并询问所应用装饰器的列表.使用此列表,您可以验证是否以正确的顺序应用了装饰器.
标签:unit-testing,decorator,c,simple-injector 来源: https://codeday.me/bug/20191119/2035459.html