java - 如何在 JUnit 测试用例中处理 wait() 方法调用?

标签 java multithreading unit-testing junit mockito

我有一个方法,它有另一个方法调用,其定义有一个 SomeIntegerObject.wait() 调用。现在,当我运行测试用例时,由于这种等待方法,测试用例一直在等待并且不执行。

我尝试在 @Test 注释中添加超时,但这会导致“测试超时”等异常。

测试方法:

private PastingResult result;
public PastingResult pasteImages(IIOImage[] images, byte pasteProcessType){
     result = new PastingResult();
     _reprocessingProvider.setListLogicHandler(this);
     //--some more method calls--
    waitForResult(); //causes my test case to wait forever and pauses execution
    return result;
}

测试用例:

@Test
    public void testPasteImagesIIOImageArrayByte() throws Exception 
    {
        ReprocessManager _reprocessingProvider1=Mockito.mock(ReprocessManager.class);
        Whitebox.setInternalState(imagePasterIfImpl, "_reprocessingProvider", _reprocessingProvider1);

        IIOImage[] images=new IIOImage[]{Mockito.mock(IIOImage.class),Mockito.mock(IIOImage.class)};
        byte pasteProcessType = 02;

        PastingResult result= imagePasterIfImpl.pasteImages(images, pasteProcessType);  
        Mockito.verify(_reprocessingProvider1).setListLogicHandler(imagePasterIfImpl);
        System.out.println(result+"is the result");
    }

waitForResult();的定义

private Integer processingWaitMonitor = new Integer(0);
private void waitForResult() {
       // synchronize to wait on the Monitor..
       synchronized(processingWaitMonitor) {
           try {
               processingWaitMonitor.wait();
           }
           catch(Exception e) {
               System.out.println("Exception during Wait !"+e);
           }
       }
   }

最佳答案

这里有两个答案:

  • 在第一级:如果您需要控制被测对象“内部”的某些内容;您可以转向 Mockito Spys 或 PowerMock 或 JMockit;因为这些框架允许在这些方面进行“ mock ”(又名获得控制权)。但在大多数情况下,这并不是一个好的做法。如果有的话,您应该将所需的功能“外包”到另一个类中;然后使用依赖注入(inject)来为您的测试设置提供该类的模拟对象。您只需在模拟对象上调用一些不执行任何操作的等待方法,而不是真正的等待。
  • 除此之外:您可以退后一步,考虑重新设计整个方法。您会看到,使用等待/通知等“低级”原语不再是好的做法。有一些抽象,例如 ExecutorService、Futures、Promises。要点是:使用 ExecutorService,您也许可以重写代码以使用 Same-Thread-Executor-Service供您测试。含义:可以重写多线程代码,这样只需为测试提供不同的执行器,所有事情就可以在单个线程上完成。不再需要等待,有保证、可靠的结果。

关于您的评论;你的代码说:

private Integer processingWaitMonitor = new Integer(0);
private void waitForResult() {

含义:您的测试类中有一个字段+私有(private)方法。假设您创建了

public interface<E> WaitService {
   public E waitForResult();
}

或者类似的东西。进而;您不必在生产类中使用锁定对象和等待方法,而只保留该服务的“某些”实例。但是,当然,这再次需要您更改生产代码。

如果你真的无法更改该代码(这有点遗憾 - 当你无法更改代码时测试代码有什么意义?)...那么 Mockito/PowerMock/JMockit 是你唯一的选择那里。

关于java - 如何在 JUnit 测试用例中处理 wait() 方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43177766/

相关文章:

python - 从Python脚本中的多个UDP套接字监听

c - C程序中线程内的多线程

java - 如何断言此单元测试中已引发 "N"异常?

java - 使用 Spring @Lazy 和 @PostConstruct 注解

Java - 如何从匿名内部类访问非最终变量?

java - 多线程的情况

c# - 起订量 应用变量

c++ - 带有单元测试的示例 C++ 项目

java - 强制 Java/Eclipse 在堆栈跟踪中提供更多信息

Java Swing - 当容器被移除时缩小窗口