【问题标题】:Dependency Injection and Unit test this constructor依赖注入和单元测试这个构造函数
【发布时间】:2011-05-19 11:18:26
【问题描述】:

我在类中有一个构造函数和一个属性:

private IMyCollectionObjects _myCollectionObjects;

public MyClassConstructor(string message)
{
     _myCollectionObjects = MyCollection.GetCollectionObejects(message);
}
  1. 请尽可能详细地帮助我了解如何单元测试这个构造函数 和 GetCollectionObjects 方法?

  2. 如何完全解耦 上课?你可以给出答案 使用任何 IoC,我想 理解这个概念。

谢谢。

【问题讨论】:

    标签: unit-testing dependency-injection c#-4.0


    【解决方案1】:

    总之,单元测试是关于单一测试的,也就是说,一次只做一件事。

    您能否详细说明一下如何单元测试此构造函数和GetCollectionObjects 方法?

    首先,您是否对MyCollection 课程进行了单元测试?

    如果没有,你应该从它开始,因为你的MyClassConstructor 类依赖它,这是依赖注入的基础。否则,你怎么知道你得到的结果是对还是错?您将无法测试并确保它完美运行。

    如何完全解耦类?您可以使用任何 IoC 给出答案,我想了解这个概念。

    我的拙见,您必须有明确的理由使用依赖注入使一个对象依赖于另一个对象。一旦你让一个对象依赖于另一个对象,在我看来,将它们解耦是没有意义的。一种解耦方式可能是使用企业库的 Unity Application Block。

    对该构造函数进行单元测试

    在测试这样的构造函数时,您通常只需要检查三件事。

    1. 构造函数不返回空值;
    2. 它返回的实例是预期的类型;
    3. 您希望通过其依赖项实例化的对象实际上已被实例化。
    [测试用例(“消息”)] 公共无效DependentConstructorTest(字符串消息){ MyClassConstructor myclass= new MyClassConstructor(message); 断言.IsNotNull(myclass); Assert.IsInstanceOf(typeof(MyClassConstructor), myclass); Assert.IsNotNull(myclass.MyCollection); // 其中 MyCollection 表示的属性 // 暴露创建的对象实例 // 你的 MyClassConstructor 类所依赖的。 }

    注意:这个测试是使用 NUnit 属性和断言方法编写的。使用任何你喜欢的东西。

    【讨论】:

      【解决方案2】:

      这大概是您需要做的事情(有一些假设)。

      假设 MyCollection 是一个静态类并且 GetCollectionObjects 解析一个字符串并返回一个 IMyCollectionObjects,您首先需要使 MyCollection 非静态,并将其传递给构造函数。类中使用的静态类/方法根据定义或多或少会产生紧密耦合。

      现在您将构建传递消息字符串和 MyCollection 的类。您的构造函数结合使用这两者来填充 IMyCollectionObjects 类型的成员变量。为了确保这按预期发生,您将需要一种从类外部检查结果的方法(即公共方法)。因此,您将需要一个公开 _myCollectionObjects 的属性获取器。

      现在您只需要从一个或多个测试中调用此构造函数,并在构造后检查属性以确保成功将字符串解析为集合。

      请注意,这实际上更像是一个集成测试,而不是一个离散的单元测试。您确实在测试解析是否成功。如果此处表示的类确实是您要测试的,那么测试实际上只是检查 GetCollectionObjects 是否被调用。该调用的结果确实无关紧要,因为您(可能)会有一个单独的测试或一组测试来确保 MyCollection 上的 GetCollectionObjects 方法按预期工作。

      【讨论】:

        【解决方案3】:

        对诸如GetCollectionObjects 等静态成员的依赖很难测试,因为您无法在运行时替换它的实现。这意味着您无法将MyClassConstructor 的实例与GetCollectionObjects 的实现细节完全隔离开来。如果没有隔离测试目标,就不能真正算是单元测试。

        See here for further discussion of static dependencies.

        您可以重构此代码以完全解耦(因此完全可测试):

        private readonly IMyCollectionObjects _myCollectionObjects;
        
        public MyClassConstructor(IMyCollectionObjects myCollectionObjects)
        {
            _myCollectionObjects = myCollectionObjects;
        }
        

        这使有关如何将消息转换为集合的知识直接从MyClassConstructor 中冒出来,使类更简单、更有凝聚力且耦合度更低。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-05-12
          • 2013-03-23
          • 1970-01-01
          • 1970-01-01
          • 2011-02-02
          • 2018-03-03
          • 2021-06-19
          • 1970-01-01
          相关资源
          最近更新 更多