使用IoC进行单元测试

如何使用IoC容器进行单元测试? 在使用IoC的巨大解决方案(50多个项目)中管理模拟是否有用? 任何经验? 在单元测试中使用它的任何C#库都可以正常工作吗?

一般来说,单元测试不需要DI容器,因为单元测试就是分离责任。

考虑一个使用构造器注入的类

public MyClass(IMyDependency dep) { } 

在整个应用程序中, IMyDependency后面可能会隐藏一个巨大的依赖关系图,但是在单元测试中,将所有这些依赖关系平铺到一个Test Double上 。

您可以使用像Moq或RhinoMocks这样的动态模拟来生成测试双精度,但这不是必需的。

 var dep = new Mock<IMyDependency>().Object; var sut = new MyClass(dep); 

在某些情况下, 自动嘲讽容器可能很好,但不需要使用生产应用程序使用的同一个DI容器。

如何使用Ioc容器进行单元测试?

IoC将强制执行编程范例,使得单元测试(即使用模拟)更容易:使用接口,没有新的(),没有单身…

但是使用IoC容器进行测试并不是一个必要条件,它只是提供一些工具,比如注入mock,但是你可以手动完成。

在使用IoC的巨大解决方案(50多个项目)中管理模拟是否有用?

我不确定你使用IoC来管理模拟的意思。 无论如何,IoC容器通常不仅仅是在测试时注入模拟。 如果你有体面的IDE支持,使重构成为可能,为什么不使用它?

任何经验?

是的,在一个巨大的解决方案中,您比以往任何时候都更需要一个不容易出错和重构的不利解决方案(即通过类型安全的IoC容器或良好的IDE支持)。

我经常在测试中使用IoC容器。 当然,它们不是纯粹意义上的“单元测试”。 国际海事组织他们更BDDish和促进重构。 测试在那里给你信心重构。 写得不好的测试可能就像在你的代码中注入水泥一样。

考虑以下几点:

 [TestFixture] public class ImageGalleryFixture : ContainerWiredFixture { [Test] public void Should_save_image() { container.ConfigureMockFor<IFileRepository>() .Setup(r => r.Create(It.IsAny<IFile>())) .Verifiable(); AddToGallery(new RequestWithRealFile()); container.VerifyMockFor<IFileRepository>(); } private void AddToGallery(AddBusinessImage request) { container.Resolve<BusinessPublisher>().Consume(request); } } 

将图像添加到图库时会发生几件事情。 图像被调整大小,生成缩略图,文件存储在AmazonS3上。 通过使用容器,我可以更容易地隔离我想要测试的行为,在这种情况下是持续的部分。

使用这种技术时,自动嘲讽容器扩展会派上用场: http : //www.agileatwork.com/auto-mocking-unity-container-extension/

使用容器能够解析像SimpleInjector这样的未注册/未知的服务, DryIoc (它的我的)可以返回模拟尚未实现的接口。

这意味着你可以用第一个简单的实现和嘲弄的依赖来开始开发,并且在你进步的时候用真实的东西代替它们。