MSTest 测试方法依赖注入

发布于 2024-10-04 09:35:57 字数 211 浏览 0 评论 0原文

我正在使用 DI 容器,并且想要使用从容器解析的实例进行 MSTest (VS 2010) 单元测试。

我想将这些实例注入到我的 TestMethod 或至少是我的 TestClass 中。这可能吗?

现在,我的 TestMethods 直接调用 container.Resolve(xxx) 我希望避免这种情况,以便我的注入测试更加真实。

I'm using a DI container and I want to do MSTest (VS 2010) unit tests with instances resolved from the container.

I'd like to get these instances injected into my TestMethod or at least my TestClass. Is this possible?

Right now my TestMethods directly call container.Resolve<T>(xxx) which I'd prefer to avoid so that my injection testing is more realistic.

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

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

发布评论

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

评论(2

淡看悲欢离合 2024-10-11 09:35:57

测试类的实例化发生在 MSTest 框架的内部类深处,因此向其中注入依赖项将是一项具有挑战性的任务。

The instantiation of the test class happens deeply in the internal classes of the MSTest framework so injecting dependencies into it would be a challenging task.

眼眸 2024-10-11 09:35:57

对我来说,根据依赖注入模式编写代码并使用 IoC 框架的主要原因是为了获得可测试的代码。然而,在测试代码中使用 IoC 容器会得到相反的结果。从你的问题我可以看出你已经经历过这个。

当使用服务定位器 (SL) 模式而不是依赖项注入 (DI) 模式时,这尤其是问题。使用 SL 模式,类直接调用 IoC 容器(或此类容器的抽象),而不是为类提供所需的依赖项(使用构造函数注入)。由于类直接调用容器,因此您还需要在测试环境中配置该容器。这很痛苦,因为测试配置或伪造对象通常变得非常复杂,因为您经常希望在每个测试的基础上影​​响伪造的行为,同时保持线程安全,因为测试框架可能会并行运行您的测试( MSTest 就是这样做的)。我知道我过去写过一些疯狂的线程安全测试代码,然后才发现我做错了:-(。

所以你应该在你的应用程序代码中使用 DI 模式,并且在你的测试中你应该连接这些例如,当对依赖于 ICustomerService 类的 HomeController 类进行测试时,您通常应该有一个 CreateController() 或测试类中的 CreateValidController 工厂方法集中了 HomeController 的创建,这使您不必在每个测试中编写这些依赖项,从而在测试代码中造成维护噩梦。在此工厂方法中,您可以通过执行以下操作手动注入例如 FakeCustomerService 类:

private static HomeController CreateController(
    InMemoryDataMapper mapper)
{
    var uowFactory = new FakeNorthwindUnitOfWorkFactory()
    {
        UnitOfWork = new NorthwindUnitOfWork(mapper);
    };

    return new HomeController(new FakeCustomerService(uowFactory));
}

这样的工厂方法的外观当然取决于(没有双关语)的依赖结构>HomeController

长话短说,不要尝试像在应用程序代码中那样在测试代码中进行依赖注入。测试框架不仅使执行此操作变得非常困难,而且还意味着您必须为测试环境配置 IoC 框架,在这种情况下您将走向失败。不幸的是,我是根据经验说话的。

The main reason -for me- for writing code according to the Dependency Injection pattern and using IoC frameworks is to get testable code. Using a IoC container in your test code however, will get the opposite result. From your question I can see that you are already experiencing this.

This is especially the problem when using the Service Locator (SL) pattern instead of the Dependency Injection (DI) pattern. With the SL pattern, a class calls the IoC container (or an abstraction of such a container) directly, instead of supplying the class with the dependencies it needs (using constructor injection). Because classes are calling the container directly, you need to configure that container in your test environment as well. This is painful because the test configuration or fake objects is often gets very complex, because you often want to influence the behavior of a fake on a per test basis, while keeping things thread-safe, because testing frameworks might run your tests in parallel (MSTest does this). I know I wrote some crazy thread-safe test code in the past, before I found out that I was doing it all wrong :-(.

So you should use the DI pattern in your application code and in your tests you should hook up those dependencies manually. For instance, when having tests for a HomeController class that depends on a ICustomerService class, you should typically have a CreateController() or CreateValidController factory method in your test class that centralizes the creation of that HomeController. This saves you from writing those dependencies in every test and thus creating a maintenance nightmare in your test code. In this factory method you inject for instance a FakeCustomerService class manually, by doing something like this:

private static HomeController CreateController(
    InMemoryDataMapper mapper)
{
    var uowFactory = new FakeNorthwindUnitOfWorkFactory()
    {
        UnitOfWork = new NorthwindUnitOfWork(mapper);
    };

    return new HomeController(new FakeCustomerService(uowFactory));
}

How such a factory method looks like of course depends (no pun intended) on how the dependency structure of the HomeController looks like.

Long story short, do not try to do dependency injection in your test code the same way as you want to do in your application code. Not only do test frameworks make it very hard to do this, it would mean you have to configure your IoC framework for your test environment, in which case you will be heading to failure. Unfortunately, I talk from experience.

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