单元测试中IContainer能否跨方法持久化?未释放是否影响测试?
单元测试中使用Autofac的性能问题排查
我在单元测试里大量用Autofac,原因有两个:一是通过容器解析组件更简单,二是能测试Autofac的注册逻辑——注册确实可能出bug,而且这种方式和实际应用场景更贴近。
我通常的写法是这样的:
[Test] [Timeout(/* some timeout */)] public void RunTest() { var builder = new ContainerBuilder(); // Registration builder.RegisterType<ConsoleOutput>().As<IOutput>(); // Build the container. var container = builder.Build(); // Resolve an instance of the IOutput interface from the container. var output = container.Resolve<IOutput>(); //use the output }
注意:所有测试里我都没把容器放在using块里,而且每个测试都会新建ContainerBuilder和IContainer。
现在遇到个问题:批量运行所有测试时,部分测试会耗时极长,触发Timeout属性导致失败;但单独重跑这些失败的测试时,却能快速完成且没有问题。
我不确定原因,但会不会是因为没正确释放IContainer,导致残留资源影响后续测试运行?
大概率是未释放IContainer导致的资源累积问题。IContainer实现了IDisposable接口,没手动释放的话,它持有的组件实例、内存资源不会及时被GC回收,当批量运行大量测试时,这些未释放的资源会不断累积,导致内存占用飙升、GC频繁触发,最终拖慢测试运行速度,触发超时。
解决方法很简单:
- 把
IContainer放在using块里,确保测试结束后自动释放资源:[Test] [Timeout(/* some timeout */)] public void RunTest() { var builder = new ContainerBuilder(); builder.RegisterType<ConsoleOutput>().As<IOutput>(); // 用using包裹容器,自动释放 using (var container = builder.Build()) { var output = container.Resolve<IOutput>(); // 使用output } } - 如果测试里有从容器解析的
IDisposable组件,也要确保这些组件被正确释放(要么让容器管理生命周期,要么手动释放)。
另外,批量测试时的环境和单测不同,单测时系统资源充足,GC压力小,所以不会出现超时;但批量运行时资源被大量占用,累积的未释放资源就会引发性能问题。
内容的提问来源于stack exchange,提问作者Graviton
相关产品推荐
相关产品推荐

