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 的任何帮助(真的没关系)如何设置所有这些?此外,受保护的事实让我更加无能为力,因为正确的标准是将单元测试放在另一个包中。

4

1 回答 1

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:

public class SutTss extends Sut {
  @Override
  public Foo methodToTest(Param param) {  // visibility loosen
    return super.methodToTest(param);
  }
}

然后你可以自由地测试那个受保护的方法(我相信它很少在 Java 中使用,因为我们总是可以通过将测试放在与 SUT 相同的包下来调用受保护的方法)

于 2012-09-07T04:12:14.673 回答