依赖注入和单元测试此构造函数

时间:2010-12-02 23:28:14

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

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

private IMyCollectionObjects _myCollectionObjects;

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

  2. 如何彻底解耦     班?你可以给出答案     使用任何IoC,我想     理解这个概念。

  3. 谢谢。

3 个答案:

答案 0 :(得分:3)

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

See here for further discussion of static dependencies.

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

private readonly IMyCollectionObjects _myCollectionObjects;

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

这使我们知道如何将消息转换为MyClassConstructor中的集合,从而使类更简单,更具凝聚力,更少耦合。

答案 1 :(得分:1)

总而言之,单元测试都是关于单一测试,即一次一件事。

  

您可以帮助我了解如何单元测试此构造函数和GetCollectionObjects方法吗?

首先,您是否对您的MyCollection班级进行了单元测试?

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

  

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

我谦虚的观点,你必须有一个明确的理由使用依赖注入使对象依赖于另一个。一旦你使一个物体依赖另一个物体,在我看来,将它们分离是毫无意义的。解耦的一种方法可能是使用企业库的Unity应用程序块。

  

单元测试此构造函数

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

  1. 构造函数不返回空值;
  2. 它返回的实例是预期的类型;
  3. 您期望通过其依赖关系实例化的对象实际上已经被填充。​​
  4.     [TestCase("message")]
        public void DependentConstructorTest(string message) {
            MyClassConstructor myclass = new MyClassConstructor(message);
    
            Assert.IsNotNull(myclass);
            Assert.IsInstanceOf(typeof(MyClassConstructor), myclass);
            Assert.IsNotNull(myclass.MyCollection); // Where MyCollection represents the property that 
                                                    // exposes the instance created of the object from
                                                    // which your MyClassConstructor class depends on.
        }
    

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

答案 2 :(得分:1)

以下是您需要做的事情(有一些假设)。

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

现在,您将构建传递消息字符串和MyCollection的类。构造函数使用这两个组合来填充IMyCollectionObjects类型的成员变量。为了确保按预期发生这种情况,您需要一种方法来检查类外部的结果(即公共方法)。所以你需要一个暴露_myCollectionObjects的属性getter。

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

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