我正在使用Java 6和Junit 4.12。我试图在JUnit中检测是否从一个类生成了一个线程。在我的班上,我像这样生成线程
final Thread deletethirdpartyClassThread = new Thread(new Runnable(){
@Override
public void run()
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.error(e.getMessage(), e);
}
final String threadName = "deletethirdpartyClass:" + myId;
Thread.currentThread().setName(threadName);
m_thirdpartySvc.deleteObject(myId);
}
});
deletethirdpartyClassThread.start();
但是,在我的JUnit测试中,当我尝试获取正在运行的线程列表时,上面的内容从未出现过。以下是我试图获取线程列表的方法
boolean threadSpawned = false;
final Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
for (final Thread t : threadSet) {
if (StringUtils.equals(t.getName(), "deletethirdpartyClass:" + myId))
{
threadSpawned = true;
break;
} // if
} // for
有没有更好的方法来列出线程,还是有另一种方法可以检测线程是否产生?
答案 0 :(得分:0)
看来你过于复杂了。让线程在开始运行时设置一个标志,并让你的单元测试检查该标志,看它是否曾经设置过。
例如,如果多个&#34; myId&#34;值是可能的:创建一个公共静态HashMap
(我称之为s_threadFlags
),用于映射&#34; myId&#34; Boolean
值的关键字,让run()
方法设置为&#34; myId&#34;该映射中的值为Boolean.TRUE
,并使单元测试类获取该键的值。
线程代码可以是:
public static Map s_threadFlags;
public static void clearThreadFlags() { s_threadFlags = null; };
public static void initThreadFlags() { s_threadFlags = new HashMap(); };
final Thread deletethirdpartyClassThread = new Thread(new Runnable(){
@Override
public void run()
{
if (s_threadFlags != null) {
s_threadFlags.put(myId, Boolean.TRUE);
}
m_thirdpartySvc.deleteObject(myId);
}
});
deletethirdpartyClassThread.start();
并且单元测试代码可以简化为:
boolean threadSpawned = (MyThreadClass.s_threadFlags.get(myId) == Boolean.TRUE);
添加:
MyThreadClass.initThreadFlags()
MyThreadClass.clearThreadFlags()
以清理。答案 1 :(得分:0)
向您的班级中注入ThreadFactory
并使用 it 创建新主题,而不是调用Thread::new
。然后,JUnit测试可以轻松注入自定义ThreadFactory
并验证是否要求创建新的Thread
。
private final ThreadFactory threadFactory;
private final Thread deletethirdpartyClassThread;
public YourClass(ThreadFactory threadFactory) {
this.threadFactory = threadFactory;
deletethirdpartyClassThread = threadFactory.newThread(new Runnable(){
@Override
public void run()
{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
LOG.error(e.getMessage(), e);
}
final String threadName = "deletethirdpartyClass:" + myId;
Thread.currentThread().setName(threadName);
m_thirdpartySvc.deleteObject(myId);
}
});
}
并自定义滚动ThreadFactory
:
class MyThreadFactory implements ThreadFactory {
private AtomicInteger invocationCounter = new AtomicInteger();
@Override
public Thread newThread(Runnable runnable) {
invocationCounter.incrementAndGet();
return new Thread(runnable);
}
public int numberOfInvocations() {
return invocationCounter.get();
}
}
如果您使用Mockito,则只需使用spy()
代替。
在测试中,您可以这样做:
public void test() {
MyThreadFactory threadFactory = new MyThreadFactory();
YourClass yourClass = new YourClass(threadFactory);
yourClass. // invoke method under test
assertThat(threadFactory.numberOfInvocations()).isEqualTo(1);
}