首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用JUnit返回多个值的测试API

使用JUnit返回多个值的测试API
EN

Stack Overflow用户
提问于 2011-06-05 13:32:54
回答 4查看 4.5K关注 0票数 2

我想测试一个API,它接收一个参数并返回一个集合。测试使用参数调用API,并检查返回的集合是否包含预期值。

假设我必须用参数arg1arg2arg3测试API,并检查返回的集合中是否出现了abc值。也就是说,我的测试用例看起来如下:

  • 使用arg1调用API并检查abc是否出现在返回的集合中。
  • 使用arg2调用API并检查abc是否出现在返回的集合中。
  • 使用arg3调用API并检查abc是否出现在返回的集合中。

如何用Junit 4开发这个测试用例?如果我必须添加arg4怎么办?如果我必须检查d值是否出现在返回的集合中怎么办?我能从配置中读取参数和期望值的列表吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-05 13:58:01

流利断言

首先,使用FEST-断言库引入具有有意义的错误消息的令人愉快的断言:

代码语言:javascript
复制
assertThat(method(arg1)).containsExactly(a, b, c);
assertThat(method(arg2)).containsExactly(a, b, c);
assertThat(method(arg3)).containsExactly(a, b, c);

BDD方式

但我理解您的问题不是语法问题,而是方法学问题:如果需要测试arg4,您应该做什么?如果arg1通过arg4具有不同的语义含义,那么我建议您对每个参数进行单独的测试。非常冗长,但也非常可读性(伪代码):

代码语言:javascript
复制
@Test
public void shouldReturnAbcWhenSomeArgumentUsed() {
  //given
  Object arg = arg1;

  //when
  Set<Object> result = method(arg);

  //then
  assertThat(result).containsExactly(a, b, c);
}

..and在每次测试中都会重复这个步骤。关键部分是:方法名称应该表示参数的含义,这个方法实际上测试了什么,您期望什么,场景是什么?

考虑测试isEven方法。我建议进行以下测试:

  • shouldReturnTrueForZero
  • shouldReturnTrueForSmallPositiveEvenNumber
  • shouldReturnTrueForLargePositiveEvenNumber
  • shouldReturnFalseForSmallPositiveOddNumber
  • shouldReturnFalseForLargePositiveOddNumber
  • ..。并对负数进行镜像测试

每个测试代表了一个稍微不同的、定义良好的场景。另一方面,您可能生成数千个shouldReturnFalseWhen227,但是这样一个测试套件的价值是什么,除非它很大?测试语义上不同的参数和角用例,精确地定义正在测试的用例。

参数化方式

如果您真的想拥有一个通用的测试方法,那么参数化运行程序就是最好的选择。我认为这个例子是不言自明的。注意:你也可以参数化期望值。

代码语言:javascript
复制
@RunWith(value = Parameterized.class)
public class JunitTest6 {

    private Object arg;

    public JunitTest6(Object arg) {
        this.arg = arg;
    }

    @Parameterized.Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(
                new Object[][]{
                        {arg1},
                        {arg2},
                        {arg3}
                });
    }

    @Test
    public void testMethod() {
        assertThat(method(arg)).containsExcatly(a, b, c);
    }

}

基于

票数 4
EN

Stack Overflow用户

发布于 2011-06-05 13:41:03

我通常会向汉克雷斯特求助于这样的东西--它是一个用于声明性地编写“matcher”的库,它与JUnit的关系非常好。

然而,关于这样的问题指出,尽管可以使用Hamcrest来完成这一任务,但更简单的方法是使用来自java.util.Collection的containsAll方法:

代码语言:javascript
复制
ArrayList<Integer> expected = new ArrayList<Integer>();
expected.add(1); expected.add(2); expected.add(3);

assertTrue(actual.containsAll(expected));
票数 3
EN

Stack Overflow用户

发布于 2011-06-05 14:24:31

在方法方面:

“敏捷”方式

测试需要持续的开发和重构,就像生产代码一样。同样,像YAGNI这样的原则(“你不会需要它”)也适用。如果现在您只需要测试abc,那么我将从一个普通的硬编码单元测试开始。如果稍后您的测试用例开始变得重复,那么一定要考虑如何重构它们。

或者你现在已经到了那个阶段,但是在我看来,这个问题并没有提供足够的信息来给出一个关于如何重构单元测试的更具体的建议。从XML读取测试?生成组合测试数据?参数化转轮(如per @Tomasz)?也许我还没有很好地理解这个问题,但问题似乎仍然太抽象了。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6243242

复制
相关文章

相似问题

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