如何使用 PowerMock 测试线程



有一段代码我试图测试,

它是这样的:

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

那么我如何在运行函数中测试代码。我正在使用电源模拟,

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

我仍然是一个初学者。

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

取决于您要测试的内容。

如果要测试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 和 test 来模拟这个 Runnable(在你的单元测试中):

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

这就是将多线程应用程序转换为仅用于测试的单线程的方式。

据我了解,主要问题是异步。测试检查结果之前,我们将从 invokeLater() 块中获取结果。因此,我们需要等到 EDT 运行我们的代码并在检查之后。我们可以通过带有空可运行块的 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 测试模式中找到了一些更多信息:

由于可运行的队列是 FIFO,因此可运行项调度在 在应用程序发布的所有任务之后结束,当它最终结束 执行一个可以确保应用程序的所有延迟任务在 AWT 事件队列也结束了。请参阅数据编辑器支持测试.java 有关应用程序代码需要等待的测试示例 完成发布到 AWT 事件线程的一些操作。

相关内容

  • 没有找到相关文章

最新更新