Java 执行JUnit测试用例时发生堆栈溢出错误

Java 执行JUnit测试用例时发生堆栈溢出错误,java,unit-testing,junit,mockito,stack-overflow,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); _dest

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

下面是正在测试的方法

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)的定义,包含此方法的类是一个抽象类,此方法被无限递归调用,从而导致堆栈溢出错误

此方法在
公共抽象类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)

\u nextNode
指的是

添加支票:

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

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

由于您使用的是PowerMockito,您应该能够通过以下方式抑制对AbstractClass中方法的任何调用:

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

我创建了一个线程来控制递归调用发生的次数。在线程中,我使用类的mock对象设置了变量
\u nextNode
,该类扩展了包含递归方法的抽象类。调用方法指定的次数后,变量
\u 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);
AutoPrintEndPoint autoPrintEndPointMock=Mockito.mock(AutoPrintEndPoint.class);
新线程(){
@凌驾
公开募捐{
对于(int i=0;i<5;i++){
试一试{
睡眠(500);
}捕捉(中断异常e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
autoPrintEndPoint.setNextNode(autoPrintEndPointMock);
}
autoPrintEndPoint.setNextNode(空);
}
}.start();
autoPrintEndPoint.configure(配置);

你能包括堆栈跟踪吗?@NikolaStojiljkovic我已经添加了堆栈跟踪,似乎我太累了。太需要咖啡了。但好吧,那么你必须退一步,提供一个真正的解决方案;因为了解自动打印端点的来源是绝对必要的。好吧,很抱歉。我将编辑我的帖子并提及它。我想我没有注意到我忽略了那个细节
我调用此函数是为了进入if条件并检查变量
mgr
是否已初始化。很遗憾,我无法修改实现。能否设置
\u nextNode
?是的,我有一个setter来设置
\u nextNode
。但是,即使我设置了它,我也会得到堆栈溢出错误。您将它设置为什么?我将它设置为抽象类的模拟对象。set方法也在抽象类中声明。我在Syntax部分中声明的MethodsDeclared中遇到一个错误抱歉应该提到它是MemberMatcherys的一个静态方法这是可行的,但是如果将来有人删除我已抑制的方法调用,它不会违反实现的设计吗,那么我的测试用例应该失败,因为我正在测试所有的可能性。如果我抑制,那么即使修改了实现,我的测试用例也会通过。