使用IoC进行单元测试

cra*_*her 97 c# unit-testing mocking inversion-of-control

如何将IoC容器用于单元测试?使用IoC在大型解决方案(50多个项目)中管理模拟是否有用?有经验吗?任何C#库在单元测试中都能很好地使用它吗?

Mar*_*ann 124

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

考虑使用Constructor Injection的类

public MyClass(IMyDependency dep) { }
Run Code Online (Sandbox Code Playgroud)

在您的整个应用程序中,可能隐藏了一个巨大的依赖关系图IMyDependency,但在单元测试中,您将其全部展平为单个Test Double.

您可以使用Moq或RhinoMocks等动态模拟来生成Test Double,但这不是必需的.

var dep = new Mock<IMyDependency>().Object;
var sut = new MyClass(dep);
Run Code Online (Sandbox Code Playgroud)

在某些情况下,自动模拟容器可能很好用,但您不需要使用生产应用程序使用的相同DI容器.

  • 同意......除非测试目标有一个IoC容器*作为依赖项,否则你的测试不需要它们......当你进行单元测试时,你将删除大部分对象图. (13认同)
  • @Mark Seemann这是有道理的......但是集成测试呢?也就是说,我玩过UI测试,当我不得不分享组合根时,我遇到了一些情况.任何意见? (4认同)
  • @Arnis L.:对于集成测试,它不那么重要.您可以选择使用DI容器连接组件,但如果是这样,您可能需要与完整应用程序不同的容器配置 - 除非您执行皮下测试或完整的系统测试,在这种情况下您可以重用应用程序的Container配置. (4认同)

Pas*_*ent 18

如何将Ioc容器用于单元测试?

IoC将强制执行编程范例,使单独测试(即使用模拟)变得更容易:使用接口,没有new(),没有单例......

但是使用IoC容器进行测试并不是真正的要求,它只会提供一些设施,例如注入模拟但你可以手动完成.

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

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

有经验吗?

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


Mik*_*nty 17

我经常在测试中使用IoC容器.当然,它们不是纯粹意义上的"单元测试".IMO他们更加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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 短语"喜欢将水泥浇注到代码中".我一直都在使用它. (8认同)