2012-09-07 38 views
1

我一直在推动自己学习越来越多的单元测试技术,并且遇到了一些我无法想象的东西,即如何开始。我试图用一种非常非常简单的单一方法对工厂进行单元测试。我已经使用示例名称为您提供帮助的人简化了它。难度单元测试带接口的工厂

public class HandlerFactory extends SecondHandlerFactory 
{ 
    //To hold singleton of this class. 
    private static SecondHandler factoryInstance = null; 

    private HandlerFactory() throws HandlerCreationException 
    { 
      super(); 
    } 

    protected InterfaceExample createSomethingByThisKey(String key) throws HandlerCreationException 
    { 
     InterfaceExample myNewHandler = null; 

     if (StringFunctions.isEqualIgnoreCase(key, "Phone")) 
     { 
      myNewHandler = new PhoneHandler(); 
     } 
    } 
} 

我在设置这个测试甚至陷入createSomethingByKey()时遇到了很大的麻烦。即使如此,我甚至无法弄清楚如何正确地执行我的assertEquals()方法。

现在,我已经设置了一些东西来做一个createInstance();但对于我如何陷入困境似乎没有任何意义。添加的变量和接口让我感到困惑。测试看起来很简单,而且是一个非常非常短的类,但没有被暴露(Java甚至不是我的第一语言)对我来说是一道难以逾越的障碍)。

有关如何设置标准JUnit或Mockito(无所谓)如何设置所有这些的任何帮助?另外,被保护的事实让我更加无能为力,因为正确的标准是在另一个软件包中进行单元测试。

+3

我们是否真的对一家工厂进行单元测试?您应该测试工厂创建的对象。 – Jayan

+0

关于测试结构化:最好在同一个包中进行测试,以便在需要时调用包可见方法。尽管测试应该位于不同的文件夹(测试源树)中。 – Jayan

+0

你说的对象应该被测试是正确的(我有,为电话,电子邮件等创建了几个处理程序),但是测试处理程序创建者本身以确保非特定键被丢弃并不重要吗?例如,如果某个键值为空或空值。在这个工厂中有一个无效的条件,我忽略了这个例子,但我觉得这是重要的测试,我只是不知道如何。 – notMordecai

回答

2

老实说,我不知道你有什么困难。我只能猜测2:

  1. 你不知道在这样的工厂测试什么。
  2. 你有问题测试一个受保护的方法

为1,这其实并不难,只是假设你正在测试的方法是公开的:

public class HandlerFactory extends SecondHandlerFactory 
{ 
    public InterfaceExample createSomethingByThisKey(String key) throws HandlerCreationException 
    { 
     InterfaceExample myNewHandler = null; 

     if (StringFunctions.isEqualIgnoreCase(key, "Phone")) 
     { 
      myNewHandler = new PhoneHandler(); 
     } 
    } 
} 

该方法的逻辑只需创建一个基于密钥的处理程序实例。因此,您的测试应该根据您的密钥来确定是否创建了正确类型的处理程序。因此,测试应该是这样的:

@Test 
testCreateSomethingByThisKeyGivenKeyForPhoneKey { 
    InterfaceExample result = handelerFactory.createSomethingByThisKey("Phone"); 
    assertTrue("result is a PhoneHandler", result instanceof PhoneHandler); 
} 

@Test 
testCreateSomethingByThisKeyGivenKeyForUnknownKey { 
    InterfaceExample result = handelerFactory.createSomethingByThisKey("NONEXIST"); 
    assertNull("result", result); 
} 

对于问题2(限制访问到受保护的方法),通常有2种选择: 我们通常有测试坐在同一个包中被测系统(SUT)所以你应该能够调用受保护的方法。

您也可以选择创建一个特定于测试的子类(TSS),它公开一个直接委托给SUT中受保护方法的方法(或覆盖以放宽方法的可见性),并根据TSS。当然,你应该确保你的SUT可以扩展。它可能看起来像这样

public class Sut { 
    protected Foo methodToTest(Param param) { 
    //.... 
    } 
} 

这样创建TSS:

​​

然后你就可以在该保护法自由测试(这是罕在Java中使用,我相信,怎么我们可以随时调用通过在与SUT相同的封装下进行测试的保护方法)

+0

非常感谢。这是问题2我无法弄清楚的问题。为了考虑“正确的指导方针”,我试图将测试保存在不同的文件夹/软件包中,但是这已将其清除了很多。我知道这是一个简单的答案,但我真的不知道。谢谢! – notMordecai