执行JUnit测试用例时出现堆栈溢出错误

时间:2017-03-24 09:12:59

标签: java unit-testing junit mockito stack-overflow

我正在编写单元测试的方法有一个方法调用,它引用一个方法在另一个类中,它是一个抽象类。该方法是递归调用的,当我执行我的测试用例时,它会产生堆栈溢出错误。

以下是测试中的方法

public void configure(Hashtable config) throws PipeBrokenException
  {
    // Configure the Pipe Element ...
    _source = (String) config.get(this.IMAGE_SOURCE);
    _destination = (String) config.get(this.IMAGE_DESTINATION);
    _printer = (XrayPrinterIf) config.get(this.PRINTER_INTERFACE);
    _configProvider = (AutoPrintConfigProvider) config.get(this.AUTOPRINT_CONFIG_PROVIDER);
     TraceLogger.getApplicationLogger().info("AutoPrintEndPoint Configure.. useTaskManager = " +useTaskManager);
    if(useTaskManager)
    {
        mgr = new AutoPrintTaskManager(this);
    }
    super.configure(config);//this method call gives a stack overflow error, when I comment this my test case runs fine.
  }

下面是方法调用super.configure(config);的定义,包含此方法的类是一个抽象类,并且这个方法被无休止地递归调用,给出了堆栈溢出错误。

此方法在public abstract class AnAbstractClass

中定义
public abstract class AnAbstractClass{
public void configure(Hashtable properties) throws PipeBrokenException
  {
    if( _nextNode != null)
    {
      _nextNode.configure(properties);
    }
  }
}

这是我的JUnit测试用例,我仍然是业余爱好者并且学习,请随时在我错误的地方纠正我,并希望解决我所面临的错误。

@InjectMocks
    AutoPrintEndPoint autoPrintEndPoint = PowerMockito.spy(new AutoPrintEndPoint("pipeName")); //AutoPrintEndPoint is the class under test
@Test
    public void testConfigureHashtable() throws PipeBrokenException 
    {
      //  SmartPipeNode node=Mockito.mock(SmartPipeNode.class,Mockito.CALLS_REAL_METHODS);

        AutoPrintConfigProvider autoPrintConfigProvider=Mockito.mock(AutoPrintConfigProvider.class); //AutoPrintConfigProvider is an interface
        XrayPrinterIf _printerIf=Mockito.mock(XrayPrinterIf.class);//XrayPrinterIf  is an interface
        Hashtable config=new Hashtable();
        config.put(AutoPrintEndPoint.IMAGE_SOURCE,"Source");
        config.put(AutoPrintEndPoint.IMAGE_DESTINATION,"Destination");
        config.put(AutoPrintEndPoint.PRINTER_INTERFACE,_printerIf);
        config.put(AutoPrintEndPoint.AUTOPRINT_CONFIG_PROVIDER,autoPrintConfigProvider);
        autoPrintEndPoint.configure("useTaskManager","yes");

        //Mockito.doNothing().when(autoPrintEndPoint).configure(config);


        autoPrintEndPoint.configure(config);
        String _source=Whitebox.getInternalState(autoPrintEndPoint, "_source");
        String _destination=Whitebox.getInternalState(autoPrintEndPoint, "_destination");
        System.out.println(_destination+"hello destination");
        System.out.println(_source+"here");
    }

堆栈跟踪

java.lang.StackOverflowError
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(Unknown Source)
    at java.security.SecureClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.defineClass(Unknown Source)
    at java.net.URLClassLoader.access$100(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at org.powermock.core.classloader.MockClassLoader.loadModifiedClass(MockClassLoader.java:178)
    at org.powermock.core.classloader.DeferSupportingClassLoader.loadClass(DeferSupportingClassLoader.java:68)
    at java.lang.ClassLoader.loadClass(Unknown Source)

3 个答案:

答案 0 :(得分:1)

由于您使用的是PowerMockito,因此您应该能够禁止对AnAbstractClass中方法的任何调用:

PowerMockito.suppress(MemberMatcher.methodsDeclaredIn(AnAbstractClass.class));

答案 1 :(得分:0)

_nextNode是指this

添加支票:

if (_nextNode != null && _nextNode != this) {
  _nextNode.configure(properties);
}

如果可以使用循环链接,则必须跟踪集合中访问的所有节点,并检查您是否再次访问节点。

答案 2 :(得分:0)

我创建了一个线程来控制递归调用的次数。在线程中,我使用类的模拟对象设置变量_nextNode,该类扩展了包含递归方法的抽象类。调用该方法指定的次数后,变量_nextNode将设置为null。我希望这个答案有用。 下面是我编写的代码片段,用于纠正我的情况下的堆栈溢出错误

AutoPrintEndPoint autoPrintEndPointMock = Mockito.mock(AutoPrintEndPoint.class);
        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 5; i++) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    autoPrintEndPoint.setNextNode(autoPrintEndPointMock); 
                }
                autoPrintEndPoint.setNextNode(null);

            }
        }.start();
        autoPrintEndPoint.configure(config);