6

我正在尝试学习依赖注入并且在对应用程序进行单元测试时遇到了问题。

我正在编写一个控制台应用程序,容器是在 Main() 中创建和初始化的,它可以作为get-propertyin 使用Program.Container,所以我可以在我的应用程序的任何地方调用Program.Container.Resolve<..>().

我有一个这样的 ServiceValidator 类:

public class ServiceValidator
{
    private readonly IConfiguration _configuration;
    private readonly IService _service;

    public ServiceValidator(IConfiguration configuration, IService service)
    {
        _configuration = configuration;
        _service = service;
    }

在我使用的另一堂课中

ServiceValidator serviceValidator = Program.Container.Resolve<ServiceValidator>();
serviceValidator.VerifyVersion();

这是调用Program.Container.Resolve导致我在单元测试中出现问题的原因,因为它尚未设置。

在容器上调用 resolve 是一种不好的做法吗?我可以在其中创建 ServiceValidator 实例Main()并传递对象,但这似乎很愚蠢,因为它会导致对象的大量参数被传递给下一个方法。

所以我想在一个类中调用 Resolve 是可以接受的,但是必须为单元测试配置容器。我应该怎么做,我应该将容器移动到程序类之外的另一个地方吗?你会推荐什么?

如果重要的话,我正在使用 Unity 和 C#

谢谢 :-)

4

5 回答 5

8

在容器上调用 resolve 是一种不好的做法吗?我可以在 Main() 中创建 ServiceValidator 实例并传递对象,但这似乎很愚蠢,因为它会导致刚刚传递给下一个方法的对象的大量参数。

当您一直使用依赖注入时,您将不需要向对象传递大量参数。每个对象的构造函数应该只具有它自己直接使用的那些依赖项作为参数——它不会知道其直接依赖项的传递依赖项。

因此,如果您有一个需要 ServiceValidator 的类 X,那么类 X 将有一个 ServiceValidator 类型的构造函数参数。然后如果某个类 Y 使用类 X,那么类 Y 将有一个类型为 X 的构造函数参数。请注意,Y对 ServiceValidator一无所知,因此您不需要将 ServiceValidator 从一个类传递到另一个类——它唯一的地方用于构建 X 时,通常由 DI 框架或仅在手写工厂的一个地方完成。

一些链接以获取更多信息:

于 2009-05-04T13:55:33.433 回答
1

我通常允许在 main 等地方调用来解决来自容器的依赖关系,尽管我仍然尝试将它们保持在最低限度。然后我要做的是在测试类的初始化方法中配置容器。对于需要调用容器的任何测试类,我都使用假实现对其进行了初始化。

不调用任何需要初始化容器的测试类然后能够忽略它并且不使用假货。我通常在这些情况下使用模拟。

我还使用Microsoft 服务定位器,以便我所采用的依赖项是 .NET Framework 中的某些内容,而不是特定容器。这让我可以在路上使用任何我想要的东西,甚至是自制的容器。

于 2009-05-04T13:37:01.620 回答
0

您可以使用静态类作为容器的初始化程序。像 BootStrapper.cs 这样的东西就可以了。然后,您可以在代码和测试中引用类方法。

于 2009-05-04T13:44:33.583 回答
0

好吧,从技术上讲,您所做的是班级中的服务地点。

我记得不久前读过这篇文章:

http://martinfowler.com/articles/injection.html

对于我的课程,我从不尝试在其中使用 Resolve。我在需要时通过容器创建对象。对于单元测试,我要么使用一些模拟库和存根类。

于 2009-05-04T13:55:20.843 回答
0

问题在于您正在尝试测试 Main 方法。这种方法几乎不可能进行单元测试。

我认为最好不要对您的 Main 方法进行单元测试,因为:

  • 现代单元测试的重点是设计
  • 您应该尽量减少对单元测试中配置的依赖。可以使用冒烟或集成测试来测试配置。
于 2009-05-04T14:24:58.883 回答