如何使用命名组件对该 IoC 注册进行单元测试? (奥特法)

发布于 2024-10-05 05:08:41 字数 757 浏览 0 评论 0原文

我正在考虑将一些复杂的创建代码转换为使用 IoC 容器 Autofac,并且因为我是 TDD 的忠实信徒,所以我正在为模块配置编写单元测试。

大多数功能都很容易测试,例如

var obj = container.Resolve<IThing>();
Assert.IsInstanceOfType(obj, typeof(ThingImplementer));

,但是我们有很多情况,我们有同一接口的多个实现者,并且不同的实现者被传递给不同的具体类。我已经通过使用命名注册解决了这个问题,例如

builder.RegisterType<ThingImplementer>().Named<IThing>("Implementer1");
builder.RegisterType<OtherImplementer>().Named<IThing>("Implementer2");
builder.Register(c => new Foo(c.ResolveNamed<IThing>("Implementer1"))).As<IFoo>();

我想不出一种编写单元测试的简单方法,以确保 Foo 获得 ThingImplementer 而不是 OtherImplementer。我想知道这是否值得付出努力,我们确实有涵盖这一点的高级集成测试,但它们没有提供单元测试所做的文档或重构优势。

你会为此编写一个单元测试吗? 如果是这样,怎么办?

I'm looking at converting some of our complex creation code to use an IoC container, Autofac, and because I'm a great believer in TDD, I'm writing unit tests for the Module configuration.

Most of the functionality is very easy to test e.g.

var obj = container.Resolve<IThing>();
Assert.IsInstanceOfType(obj, typeof(ThingImplementer));

But we have a number of cases where we have multiple implementers of the same interface and different implementers are being passed to different concrete classes. I've resolved this by using named registration e.g.

builder.RegisterType<ThingImplementer>().Named<IThing>("Implementer1");
builder.RegisterType<OtherImplementer>().Named<IThing>("Implementer2");
builder.Register(c => new Foo(c.ResolveNamed<IThing>("Implementer1"))).As<IFoo>();

What I can't figure out is an easy way to write a unit test for ensuring that Foo gets ThingImplementer and not OtherImplementer. I'm wondering if it is worth the effort, we do have high level integration tests that cover this, but they don't give the documentation or refactoring benefits that unit tests do.

Would you write a unit test for this?
If so, how?

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

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

发布评论

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

评论(2

萌逼全场 2024-10-12 05:08:41

您通常不会在单元测试中测试容器的配置。在单元测试环境中,您不使用容器来注入任何依赖项(您手动执行此操作),如果您这样做,您将注入假对象,而不是真实/生产类型。因此,容器配置通常对于您的单元测试来说是未知的。

有时我倾向于测试容器是否能够创建应用程序的根类型(例如 MVC 应用程序的控制器类或 WebForms 应用程序的 Page 类)。因为容器将实例化对象图,所以它可以让我很好地了解容器是否配置正确。但是,我对容器是否返回正确的实现不感兴趣。大多数时候,应用程序根目录甚至只有一个可访问的已注册接口的实现,因此几乎不会出错。

如果您想测试您的容器配置,也许它太复杂,您应该尝试简化您的应用程序设计,以便可以简化注册。

You would typically not test the configuration of your container in your unit tests. In your unit test environment you don't use a container to inject any dependencies (you do this by hand) and if you would do this, you would inject fake objects, and not the real/production types. Therefore the container configuration is typically unknown to your unit tests.

What I tend to do sometimes is test whether the container is able to create the application's root types (such as the controller classes of a MVC application, or the Page classes of an WebForms application). Because the container will instantiate a graph of objects, it will give me a good idea whether the container is configured correctly. However, I'm never interested if the container returns the correct implementation. Most of the time there is even only one implementation of a registered interface that is accessible for the application root, so it hardly could go wrong.

If you want to test your container configuration, perhaps it is too complex and you should try to simplify your application design so you can simplify the registration.

欢烬 2024-10-12 05:08:41

这里没有什么新内容,只是史蒂文观点的延伸。

正如史蒂文所说,这绝对不是单元测试。您也许可以将其视为一次学习测试。看一下 Ninject 测试套件 - 它展示了他们如何进行此类测试(但请记住他们正在编写一个容器)。我认为 autofac 有类似的测试。

话虽如此,如果您觉得有有趣的行为并且它不会变得不稳定,那么将其放入集成套件中也没什么坏处。

关于它是外部的事实的另一点也非常有效 - 请参阅 洋葱架构

Nothing new here, just extensions of Steven's points.

As Steven says, that's definitely not a Unit Test. You could perhaps view it as a learning test. Have a look at the Ninject test suite - it shows how they do such tests (but remember they're writing a Container). I assume autofac has similar tests.

Having said that, if you feel there's interesting behavior and it wont become flaky, it's not harm to stick it into an integration suite.

The other point regarding the fact that it's external is also very valid - see the notion of an Onion Architecture

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