首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >线程抛出异常中的junit断言

线程抛出异常中的junit断言
EN

Stack Overflow用户
提问于 2010-04-08 07:02:49
回答 5查看 24.2K关注 0票数 24

抛出异常而不是显示失败,或者我不应该在线程中有断言,这是我做错了什么?

代码语言:javascript
复制
 @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

代码语言:javascript
复制
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)
EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-04-08 07:11:34

JUnit框架仅捕获运行测试的主线程中的断言错误。它不知道来自新的派生线程的异常。为了正确执行此操作,您应该将线程的终止状态传递给主线程。您应该正确地同步线程,并使用某种共享变量来指示嵌套线程的结果。

编辑:

下面是一个通用的解决方案,可以帮助您:

代码语言:javascript
复制
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()来进行验证。测试方法将在必要时等待,并将在主线程的上下文中抛出断言错误。

票数 40
EN

Stack Overflow用户

发布于 2016-11-15 17:06:00

Eyal Schneider's answer的一个小改进

ExecutorService允许提交Callable,任何抛出的异常或错误都会被返回的Future重新抛出。

因此,测试可以写成:

代码语言:javascript
复制
@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
}
票数 14
EN

Stack Overflow用户

发布于 2010-10-26 01:27:19

在涉及多个工作线程的情况下,例如在原始问题中,仅仅连接其中一个线程是不够的。理想情况下,您希望等待所有工作线程完成,同时仍然向主线程报告断言失败,例如在Eyal的回答中。

下面是一个简单的示例,说明如何使用ConcurrentUnit来实现这一点

代码语言:javascript
复制
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
    }
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2596493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档