抛出异常而不是显示失败,或者我不应该在线程中有断言,这是我做错了什么?
@Test
public void testComplex() throws InterruptedException {
int loops = 10;
for (int i = 0; i < loops; i++) {
final int j = i;
new Thread() {
@Override
public void run() {
ApiProxy.setEnvironmentForCurrentThread(env);//ignore this
new CounterFactory().getCounter("test").increment();//ignore this too
int count2 = new CounterFactory().getCounter("test").getCount();//ignore
assertEquals(j, count2);//here be exceptions thrown. this is line 75
}
}.start();
}
Thread.sleep(5 * 1000);
assertEquals(loops, new CounterFactory().getCounter("test").getCount());
}
StackTrace
Exception in thread "Thread-26" junit.framework.AssertionFailedError: expected:<5> but was:<6>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:277)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:195)
at junit.framework.Assert.assertEquals(Assert.java:201)
at com.bitdual.server.dao.ShardedCounterTest$3.run(ShardedCounterTest.java:77)
发布于 2010-04-08 07:11:34
JUnit框架仅捕获运行测试的主线程中的断言错误。它不知道来自新的派生线程的异常。为了正确执行此操作,您应该将线程的终止状态传递给主线程。您应该正确地同步线程,并使用某种共享变量来指示嵌套线程的结果。
编辑:
下面是一个通用的解决方案,可以帮助您:
class AsynchTester{
private Thread thread;
private AssertionError exc;
public AsynchTester(final Runnable runnable){
thread = new Thread(new Runnable(){
public void run(){
try{
runnable.run();
}catch(AssertionError e){
exc = e;
}
}
});
}
public void start(){
thread.start();
}
public void test() throws InterruptedException{
thread.join();
if (exc != null)
throw exc;
}
}
您应该在构造函数中将其传递给runnable,然后只需调用start()来激活,调用test()来进行验证。测试方法将在必要时等待,并将在主线程的上下文中抛出断言错误。
发布于 2016-11-15 17:06:00
对Eyal Schneider's answer的一个小改进
ExecutorService
允许提交Callable
,任何抛出的异常或错误都会被返回的Future
重新抛出。
因此,测试可以写成:
@Test
public void test() throws Exception {
ExecutorService es = Executors.newSingleThreadExecutor();
Future<?> future = es.submit(() -> {
testSomethingThatMightThrowAssertionErrors();
return null;
});
future.get(); // This will rethrow Exceptions and Errors as ExecutionException
}
发布于 2010-10-26 01:27:19
在涉及多个工作线程的情况下,例如在原始问题中,仅仅连接其中一个线程是不够的。理想情况下,您希望等待所有工作线程完成,同时仍然向主线程报告断言失败,例如在Eyal的回答中。
下面是一个简单的示例,说明如何使用ConcurrentUnit来实现这一点
public class MyTest extends ConcurrentTestCase {
@Test
public void testComplex() throws Throwable {
int loops = 10;
for (int i = 0; i < loops; i++) {
new Thread(new Runnable() {
public void run() {
threadAssertEquals(1, 1);
resume();
}
}).start();
}
threadWait(100, loops); // Wait for 10 resume calls
}
}
https://stackoverflow.com/questions/2596493
复制相似问题