Java 抽象类保护方法junit测试用例
以代码为例:Java 抽象类保护方法junit测试用例,java,junit,Java,Junit,以代码为例: abstract public class TigerFinderPage extends TigerPage private Manager manager; protected Manager getTiger() { // If we haven't already done so, get the tiger. if (tiger== null) { try { tiger= EntityResolution.ge
abstract public class TigerFinderPage extends TigerPage
private Manager manager;
protected Manager getTiger()
{
// If we haven't already done so, get the tiger.
if (tiger== null) {
try {
tiger= EntityResolution.getTigerFromName(ResTools.resolveNoTranslation(getConfigBundle(), "tiger", ""));
} catch (Exception e) {
LogTools.error(logger, null, e);
return null;
}
}
return tiger;
}
尝试1:
public class TigerFinderPageTest {
private TigerFinderPage tigerFinderPage;
@Before
public void setUp() throws Exception {
TigerFinderPage = new TigerFinderPage () {
@Override
protected ResourceProvider getBundle() {
return null;
}
@Override
protected ResourceProvider getConfigBundle() {
return null;
}
};
}
@Test
public void testTigerManager(){
assertNull(tigerFinderPage.getTiger());
}
}
当受保护的方法在不同的包中时,如何测试它们?我已经尝试过使用反射,但不知道如何在这种情况下实现它。一个答案是遵循JUnit的最佳实践,将生产代码和测试代码都放在同一个包中,以便允许访问受保护的成员,但访问不同源文件夹中的成员,因此,非生产代码不会干扰生产代码。例如,在maven的结构中:
-- src
+-- main
+-- java
+-- org
+-- mypackage # Production code for org.mypackage
+-- test
+-- java
+-- org
+-- mypackage # Testing code for org.mypackage
如果这不是一个选项,您可以从抽象类继承并增加所述方法的可见性,以便测试可以访问它:
public class TigerFinderPageTest {
public static class TigerFinderPageDummy extends TigerFinderPage {
@Override
protected ResourceProvider getBundle() {
return null;
}
@Override
protected ResourceProvider getConfigBundle() {
return null;
}
/** Note this method is PUBLIC */
@Override
public Manager getTiger() {
return super.getTiger();
}
}
private TigerFinderPageDummy tigerFinderPage;
@Before
public void setUp() throws Exception {
tigerFinderPage = new TigerFinderPageDummy();
}
@Test
public void testTigerManager(){
assertNull(tigerFinderPage.getTiger());
}
}
测试非公共成员会将您的测试与您的实现联系起来,从而使重构变得更加困难 如果它足够重要以至于不能通过公共接口进行测试,那么它必须是独立的功能,可以存在于自己的类中 在本例中,我将为
LazyTigerFactory
创建一个单独的类和测试:
public final class LazyTigerFactory {
private Manager manager;
public Manager getTiger()
{
// If we haven't already done so, get the tiger.
if (tiger == null) {
try {
tiger= EntityResolution.getTigerFromName(ResTools.resolveNoTranslation(getConfigBundle(), "tiger", ""));
} catch (Exception e) {
LogTools.error(logger, null, e);
return null;
}
}
return tiger;
}
}
然后在课堂上使用它:
abstract public class TigerFinderPage extends TigerPage
private final LazyTigerFactory tigerFactory = new LazyTigerFactory();
protected Manager getTiger(){
return tigerFactory.getTiger();
}
利益
- 您可以在工厂测试的创建过程中获得完整的测试覆盖率,而不会使
测试变得混乱TigerFinderPage
- 您可以在以后轻松地将
更改为另一个LazyTigerFactory
具有较少的直接依赖关系TigerFinderPage
更小,更不懒惰,更不凌乱这个类的真正功能(它的单一职责)TigerFinderPage
- 您甚至可以更改为注入一个完全解耦的工厂接口,这可能有助于其他测试
是什么意思?ResTools.ResolveNotTranslation
做什么?不清楚创建Tiger
实例所需的信息来自何处。ResTools.ResolveNotTranslation
与此无关,它只是将管理器转换为西班牙语或西班牙语的实现。如果您试图测试受保护的方法,请使用反射。检查这里-如果getConfigBundle
返回null
,那么将使用null
作为第一个参数调用它。你认为这会有什么影响?当它是getTiger()
代码的一部分时,我看不出它是如何“与此无关”的。同样,我仍然不知道您希望从哪里获得信息。即使ResolveNotTranslation
返回了一些内容,EntityResolution.getTigerFromName
在您的测试环境中做什么?你在测试中调试过代码了吗?你说得对。谢谢,很抱歉,我没有说这些。这是一个生产代码,与您描述的maven结构相同。但是当我执行assertNotNull(tigerFinderPage.getTiger())时代码>它失败了。我已经对这个方法进行了调试tigerFinderPage.getTiger()
它返回一个tigerManagerProxy对象。