2008-09-01 41 views
14

我开发了一些具有类似行为的类,它们都实现了相同的接口。我实现了一个创建适当对象并返回接口的工厂。我正在为工厂写一个单元测试。你所得到的只是对象的一个​​接口。 测试工厂工作正常的最佳方法是什么?在单元测试中检查工厂的结果

我想知道Java中的答案,但是如果有跨语言的解决方案,我想知道它。

数字2.在答案中,会像其他答案一样完成?如果是这样,我将标记另一个接受的答案,并重新说明我的问题,以同时为一个接口返回的工厂和你不知道具体类实现接口的类型,以及知道具体类是什么的情况用过的。

回答

16

因为我不知道你的工厂方法的样子做的,所有我现在可以告诉是

  1. 检查看对象是你要找的正确的具体落实:

    IMyInterface fromFactory = factory.create(...); 
    Assert.assertTrue(fromFactory instanceof MyInterfaceImpl1); 
    
  2. 您可以检查工厂是否使用有效的实例变量设置具体实例。

0
if (myNewObject instanceof CorrectClass) 
{ 
    /* pass test */ 
} 

更新:

不知道为什么,这引起了下调,所以我将展开它有点...

public void doTest() 
{ 
    MyInterface inst = MyFactory.createAppropriateObject(); 
    if (! inst instanceof ExpectedConcreteClass) 
    { 
     /* FAIL */ 
    } 
} 
+4

它被标记为'因为你应该使用声明而不是测试... – Nicolas 2008-10-23 10:46:44

0

@ CEM-catikkas我认为比较getClass()。getName()值会更加正确。在MyInterfaceImpl1类是子类的情况下,您的测试可能会被破坏,因为子类是instanceof MyInterfaceImpl1。我会改写如下:

IMyInterface fromFactory = factory.create(...); 
Assert.assertEquals(fromFactory.getClass().getName(), MyInterfaceImpl1.class.getName()); 

如果你觉得这可能以某种方式(我无法想象)失败,使两个验证。

+0

我同意,但我不认为检查类名称的平等是多余的。只要检查课程应该足够好。 – 2008-09-16 03:52:06

+1

为什么要测试一个来自Class的方法返回一个相等的值,而不是直接比较Class对象? – jdmichal 2008-11-17 14:55:20

20

你所试图做的是不是单元测试

如果测试返回的对象是否是特定的,具体类的实例,你是不是单元测试。你是集成测试。虽然集成测试很重要,但这不是一回事。

在单元测试中,您只需要测试对象本身。如果在返回的抽象对象的具体类型上声明,那么您正在测试返回对象的实现。在对象

单元测试一般

在单元测试中,有四件事情,你要断言:

  1. 查询的返回值是你所期望的是什么(非空的方法)是。
  2. 命令的副作用(void方法)按照您的预期修改对象本身。
  3. 命令发送到其他对象收到(这通常使用模拟)。

此外,您只想测试从对象实例(即公共接口)中可以观察到什么。否则,你将自己绑定到一组特定的实现细节。这将要求您在这些细节更改时更改您的测试。

单元测试工厂对工厂

单元测试真的是索然无味,因为你不感兴趣的查询返回的对象的行为。这种行为(希望)可以在其他地方进行测试,可以推测,而单元测试则是对象本身。你只是真正感兴趣的是返回的对象是否有正确的类型,这是保证如果您的程序编译。

由于工厂不会随着时间而改变(因为那时它们会是“建造者”,这是另一种模式),所以没有命令可以测试。

工厂负责实例化对象,所以他们不应该依赖其他工厂为他们做这件事。他们可能依赖于一个Builder,但即便如此,我们也不应该测试Builder的正确性,只有Builder是否接收到该消息。

这意味着您需要在工厂上测试的所有内容都是他们是否将消息发送到他们所依赖的对象。如果你使用依赖注入,这几乎是微不足道的。只是嘲笑单元测试中的依赖关系,并验证它们是否收到消息。

汇总单元测试工厂的

  1. 不要测试的行为,也没有返回的对象的实现细节!您的工厂不负责执行对象实例!
  2. 测试是否收到发送给依赖项的命令。

就是这样。如果没有依赖关系,就没有什么可以测试的。除了可能断言返回的对象不是null参考。

集成测试工厂

如果你有一个要求,即返回的抽象对象类型是一个特定的具体类型的实例,那么这属于下集成测试。

此处的其他人已经回答了如何使用instanceof运算符来完成此操作。