Junit 테스트 는 '새 스 레 드 를 시작 합 니 다' 라 는 동작 이 있 을 때 순식간에 끝 나 는 문제 입 니 다.
안에 있 는 소스 코드 는 다음 과 같 습 니 다 (이전에 쓴 main 방법 은 포함 되 지 않 습 니 다).
public class Preloader {
private final FutureTask<Long> future = new FutureTask<Long>(new Callable<Long>() {
@Override
public Long call() throws Exception {
Thread.currentThread().setName("Thread(3)");
System.out.println(Thread.currentThread().getName() + ": simulate a latency ");
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": the latency is over");
return Math.round(Math.random() * 1000);
}
});
private final Thread loader = new Thread(future);
public void start() {
System.out.println(Thread.currentThread().getName() + ": start the loader");
loader.start();
System.out.println(Thread.currentThread().getName() + ": loader started");
}
public Long get() {
try {
System.out.println(Thread.currentThread().getName() + ": begin to get");
long start = System.currentTimeMillis();
Long result = future.get();
System.out.println(Thread.currentThread().getName() + ": got result: " + result);
System.out.println(Thread.currentThread().getName() + ": spent time: "
+ (System.currentTimeMillis() - start));
return result;
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ": got nothing");
return null;
}
}
당시 작 성 된 JUnit 테스트 코드 는 다음 과 같 습 니 다.
public class PreloaderTest {
/**
* Test method for {@link com.rainbow.util.futuretask.Preloader#get()}.
*/
@Test
public void testGet() {
Thread.currentThread().setName("Thread(main)");
final Preloader pl = new Preloader();
pl.start();
// try to get the result before the latency is over
new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread(1)");
pl.get();
}
}).start();
// try to get the result after the latency is over
new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread(2)");
try {
Thread.sleep(6000);
pl.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
그러나 이 테스트 코드 는 아무리 실행 하고 몇 번 을 실행 하 더 라 도 그 운행 결 과 는 상상 속 의 결과 가 아니 라 다음 과 같은 결과 입 니 다.
Thread(main): start the loader
Thread(main): loader started
Thread(3): simulate a latency
Thread(1): begin to get
결과적으로 Thread (1) Thread (2) Thread (3) 가 실행 도 안 하고 끝 났 습 니 다.
이 결과 에 대해 매우 의외 라 서 인터넷 에서 찾 아 보 았 는데 다음 과 같은 설명 을 찾 았 다.
, , Daemon system.exit , 。 eclipse Junit org.eclipse.jdt.internal.junit.runner.RemoteTestRunner。 main 。 :
public static void main(String [] args) {
try {
RemoteTestRunner testRunServer= new RemoteTestRunner();
testRunServer.init(args);
testRunServer.run();
} catch (Throwable e) {
e.printStackTrace(); // don't allow System.exit(0) to swallow exceptions
} finally {
// fix for 14434
System.exit(0);
}
}
, , , junit 。
이 단락 을 보면 위의 결 과 를 알 수 있다.
위의 이런 상황 을 피하 기 위해 내 가 생각 한 두 가지 방법:
① JUnit 을 사용 하지 않 고 스스로 main 방법 을 써 서 테스트 한다. 예 를 들 어 http://rainbow702.iteye.com/admin/blogs/2206301 그 러 하 다
② JUnit 도 사용 하지만 테스트 코드 의 마지막 에 sleep 문 구 를 추가 합 니 다. 즉, 다음 코드 의 마지막 sleep 처럼:
/**
*
*/
package com.rainbow.util.futuretask;
import org.junit.Test;
/**
* @author Rainbow
*/
public class PreloaderTest {
/**
* Test method for {@link com.rainbow.util.futuretask.Preloader#get()}.
*/
@Test
public void testGet() {
Thread.currentThread().setName("Thread(main)");
final Preloader pl = new Preloader();
pl.start();
// try to get the result before the latency is over
new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread(1)");
pl.get();
}
}).start();
// try to get the result after the latency is over
new Thread(new Runnable() {
@Override
public void run() {
Thread.currentThread().setName("Thread(2)");
try {
Thread.sleep(6000);
pl.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
하지만 이렇게 되면 sleep 이 필요 한 시간 을 정확하게 추산 해 야 한다. 아니면 아예 시간 을 정 하지 않 은 걸 로. sleep() 。
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Is Eclipse IDE dying?In 2014 the Eclipse IDE is the leading development environment for Java with a market share of approximately 65%. but ac...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.