使用 IoC 进行单元测试

发布于 2024-08-06 01:05:20 字数 85 浏览 2 评论 0原文

如何使用 IoC 容器进行单元测试?使用 IoC 管理大型解决方案(50 多个项目)中的模拟是否有用?有什么经验吗?有哪些 C# 库适合在单元测试中使用它?

How can a IoC Container be used for unit testing? Is it useful to manage mocks in a huge solution (50+ projects) using IoC? Any experiences? Any C# libraries that work well for using it in unit tests?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

苦妄 2024-08-13 01:05:20

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

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

public MyClass(IMyDependency dep) { }

在您的整个应用程序中,IMyDependency 后面可能隐藏着一个巨大的依赖关系图,但在单元测试中,您将其全部扁平化为单个 测试替身

您可以使用 Moq 或 RhinoMocks 等动态模拟来生成测试替身,但这不是必需的。

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

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

Generally speaking, a DI Container should not be necessary for unit testing because unit testing is all about separating responsibilities.

Consider a class that uses Constructor Injection

public MyClass(IMyDependency dep) { }

In your entire application, it may be that there's a huge dependency graph hidden behind IMyDependency, but in a unit test, you flatten it all down to a single Test Double.

You can use dynamic mocks like Moq or RhinoMocks to generate the Test Double, but it is not required.

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

In some cases, an auto-mocking container can be nice to have, but you don't need to use the same DI Container that the production application uses.

爱格式化 2024-08-13 01:05:20

我经常在测试中使用 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-扩展名/

I often use an IoC container in my tests. Granted, they are not "unit tests" in the pure sense. IMO They are more BDDish and facilitate refactoring. Tests are there to give you confidence to refactor. Poorly written tests can be like pouring cement into your code.

Consider the following:

[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);
    }
}

There are several things that happen when adding an image to the gallery. The image is resized, a thumbnail is generated, and the files are stored on AmazonS3. By using a container I can more easily isolate just the behavior I want to test, which in this case is the persisting part.

An auto-mocking container extension comes in handy when using this technique:
http://www.agileatwork.com/auto-mocking-unity-container-extension/

掩饰不了的爱 2024-08-13 01:05:20

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

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

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

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

我不确定你所说的使用 IoC 管理模拟是什么意思。不管怎样,在测试方面,IoC 容器通常可以做的不仅仅是注入模拟。如果您有良好的 IDE 支持使重构成为可能,为什么不使用它呢?

有什么经验吗?

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

How can a Ioc Container be used for unit testing?

IoC will enforce programming paradigms that will make unit testing in isolation (i.e. using mocks) easier: use of interfaces, no new(), no singletons...

But using the IoC container for testing is not really a requirement, it will just provide some facilities e.g. injection of mocks but you could do it manually.

Is it useful to manage mocks in a huge solution (50+ projects) using IoC?

I'm not sure what you mean by managing mocks using IoC. Anyway, IoC containers can usually do more than just injecting mocks when it comes to testing. And if you have decent IDE support that makes refactoring possible, why not using it?

Any experience?

Yes, on a huge solution, you need more than ever a non error-prone and refactoring-adverse solution (i.e. either through a type safe IoC container or good IDE support).

記柔刀 2024-08-13 01:05:20

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

这意味着您可以从第一个简单的实现及其模拟依赖项开始开发,并随着您的进展将它们替换为真实的依赖项。

Using containers with ability to resolve unregistered/uknown services like SimpleInjector, DryIoc (its mine) can return mocks for not yet implemented interfaces.

Which means that you can start development with first simple implementation and its mocked dependencies, and replace them with real thing as you progress.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文