首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如果在另一个线程中引发异常,则失败单元测试

如果在另一个线程中引发异常,则失败单元测试
EN

Stack Overflow用户
提问于 2017-08-18 15:11:34
回答 1查看 2.3K关注 0票数 6

目前,每当我需要通过测试来响应另一个线程中抛出的异常时,我就编写如下所示:

代码语言:javascript
运行
复制
package com.example;

import java.util.ArrayList;
import java.util.List;
import org.testng.annotations.Test;

import static java.util.Arrays.asList;
import static java.util.Collections.synchronizedList;
import static org.testng.Assert.fail;

public final class T {
  @Test
  public void testFailureFromLambda() throws Throwable {
    final List<Throwable> errors = synchronizedList(new ArrayList<>());

    asList("0", "1", "2").parallelStream().forEach(s -> {
      try {
        /*
         * The actual code under test here.
         */
        throw new Exception("Error " + s);
      } catch (final Throwable t) {
        errors.add(t);
      }
    });

    if (!errors.isEmpty()) {
      errors.forEach(Throwable::printStackTrace);

      final Throwable firstError = errors.iterator().next();
      fail(firstError.getMessage(), firstError);
    }
  }
}

同步列表可能会被AtomicReference<Throwable>替换,但通常情况下,代码保持不变。

是否有任何标准(且较少冗长)的方法可以使用任何可用的测试框架(http://testng.org/doc/http://junit.org/http://hamcrest.org/https://joel-costigliola.github.io/assertj/等)来进行相同的操作?

EN

Stack Overflow用户

回答已采纳

发布于 2017-08-19 03:25:52

默认情况下,当异常被抛出时,TestNG会失败。我相信JUnit也会发生同样的情况,如果它抛出意外异常,它会将测试标记为errored

如果要处理Streams,则需要将其封装在RuntimeException变体中,以便Java不会抱怨。TestNG会自动通过测试。

这是一个样本:

代码语言:javascript
运行
复制
@Test
public void testFailureFromLambdaRefactored() {
    asList("0", "1", "2").parallelStream().forEach(s -> {
        try {
        /*
        * The actual code under test here.
        */
            if (s.equals("2")) {
                throw new Exception("Error " + s);
            }
        } catch (final Throwable t) {
            throw new RuntimeException(t);
        }
    });
}

这是针对涉及lambdas和流的场景。通常,如果您希望了解从@Test方法派生出来的新线程中发生的异常,则需要使用ExecutorService

这是一个样本:

代码语言:javascript
运行
复制
@Test
public void testFailureInAnotherThread() throws InterruptedException, ExecutionException {
    List<String> list = asList("0", "1", "2");
    ExecutorService service = Executors.newFixedThreadPool(2);
    List<Future<Void>> futures = service.invokeAll(Arrays.asList(new Worker(list)));
    for (Future future : futures) {
        future.get();
    }

}

public static class Worker implements Callable<Void> {
    private List<String> list;

    public Worker(List<String> list) {
        this.list = list;
    }

    @Override
    public Void call() throws Exception {
        for (String s : list) {
            if (s.equals("2")) {
                throw new Exception("Error " + s);
            }
        }
        return null;
    }
}
票数 4
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45759903

复制
相关文章

相似问题

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