如何使用powermock测试线程?

时间:2012-10-12 06:57:04

标签: java multithreading unit-testing powermock

我试图测试一段代码,

这是这样的:

class Foo {
    //do some operations
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            //some piece of code
        }
    }
}

那么如何在run函数中测试代码呢? 我正在使用powermock,

线程是在另一个类中启动的所以我不应该在那里调用它吗?

我还是个初学者。

3 个答案:

答案 0 :(得分:0)

将在Event Dispatch Thread上调用Runnable的run()方法中的代码。通常只应在此线程上执行GUI更新。使用模拟对象来测试GUI不是一个好主意。

答案 1 :(得分:0)

取决于您要测试的内容。

如果您正在测试Foo的行为 - 请不要担心并发性。只需拨打Foo电话,并声明所获得的结果符合您的期望。只需org.junit.Assert即可。

如果您正在测试Runnable实际执行的操作,则需要首先破坏依赖关系。现在,您的类Foo依赖于某些Runnable,它在内部实例化并调用。将其转换为Foo的参数:

class Foo {
  private Runnable runnable;
  public Foo(Runnable rnbl) {
    this.runnable = rnbl;
  }
  // somewhere later in the class
  SwingUtilities.invokeLater(this.runnable);
}

现在你可以用Mockito和测试(在单元测试中)模拟这个Runnable:

Runnable mock = Mockito.mock(Runnable.class);
Foo foo = new Foo(mock);
foo.doSomething();
Mockito.verify(mock).run(); // verify that it was called

这就是您将多线程应用程序转换为单线程以进行测试的方法。

答案 2 :(得分:0)

据我所知,主要问题是异步。测试在我们从invokeLater()块获得结果之前检查结果。所以我们需要等到EDT运行我们的代码并在那之后检查。我们可以通过带有空的runnable块的invokeAndWait方法来实现。示例Foo类:

import javax.swing.SwingUtilities;

public class Foo {

    private String myLine;

    public void executeInEDT(final String line) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                myLine = line;
            }
        });
    }

    public String getLine() {
        return myLine;
    }
}

和测试方法:

@Test
public void testInvokeLater() throws InterruptedException, InvocationTargetException {
    String testLine = "Test line";
    Foo foo = new Foo();
    foo.executeInEDT(testLine);
    SwingUtilities.invokeAndWait(new Runnable() {
        @Override
        public void run() {
            // Just for sync
        }
    });
    assertEquals(testLine, foo.getLine());
    // And more asserts
}

UPD :在Netbeans test patterns中找到更多信息:

  

由于runnables的队列是FIFO,所以runnable被安排在   在应用程序发布的所有任务之后以及最终结束时结束   执行一个可以确定应用程序的所有延迟任务   AWT事件队列也结束了。请参见DataEditorSupportTest.java   有关需要在应用程序代码中等待的测试示例   完成发布到AWT事件线程的一些操作。