我试图测试一段代码,
这是这样的:
class Foo {
//do some operations
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//some piece of code
}
}
}
那么如何在run函数中测试代码呢? 我正在使用powermock,
线程是在另一个类中启动的所以我不应该在那里调用它吗?
我还是个初学者。
答案 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事件线程的一些操作。