在整个软件中使用适当的参数测试该方法

时间:2018-06-01 17:01:19

标签: java unit-testing testing methods parameters

我最近遇到了一个问题,当我使用错误的参数调用我的服务中的方法时。这导致了某种中断,所以我正在考虑将来如何防止这种情况发生。

假设我有以下方法:

public boolean doSomething(String param1, String param2);

我想验证每次调用此方法时(无论我的服务位于何处),param1值都是特定的(例如String1String2和{{1}这将是一个有效的参数值。

是否有任何技术/库/工具可以在单元测试中验证这一点?

更新:正如已接受的答案所示,这是单元测试不应涵盖的内容,因为单元测试用于行为测试。将来阻止错误调用的是使用String3或仅使用简单的参数检查。

2 个答案:

答案 0 :(得分:1)

如果可能,您应该利用编译时检查,而不是将测试推迟到运行时。如果只有三个合法值,那么param1可能应该是enum而不是String

单元测试用于以某种方式验证方法的行为。他们把这个方法当作一个黑盒子,并从外面戳它。如果您关注的名称,他们将无法提供帮助。你在这个方法里面想要验证外面的世界是否表现良好。这样做的方法是在方法开始时使用运行时前置条件检查

public boolean doSomething(String param1, String param2) {
    if (!Objects.equals(param1, "String1") &&
        !Objects.equals(param1, "String2") &&
        !Objects.equals(param1, "String3"))
    {
        throw IllegalArgumentException("param1 must be String1, 2, or 3");
    }

    ...
}

番石榴Preconditions class可能会有所帮助。

public boolean doSomething(String param1, String param2) {
    Preconditions.checkArgument(
        Objects.equals(param1, "String1") ||
        Objects.equals(param1, "String2") ||
        Objects.equals(param1, "String3"),
        "param1 must be String1, 2, or 3"
    );

    ...
}

答案 1 :(得分:1)

创建一个单元测试,确保方法在运行时只接受某些值作为param1参数。

使用两种方案对测试进行编码:有效和无效的情况。

例如在JUnit 5中:

<input ng-pattern="myPattern()">
$scope.myPattern = function(){ 
   var list = listFromServer.join('|'); 
   return new RegExp("^(?!.*("+list+")).*$")
}

测试应该失败,因为你实际上不保证。 然后改进您的实际实现以使测试通过。

例如:

@Test
public void doSomething(){ 
   Assert.AssertTrue(new Foo().doSomething("String1", "anyValue");
   Assert.AssertTrue(new Foo().doSomething("String2", "anyValue");
   Assert.AssertTrue(new Foo().doSomething("String3", "anyValue");
}

@Test
public void doSomething_with_illegal_argument(){ 
    Assert.assertThrows(IllegalArgumentException.class, () -> new Foo().doSomething("invalidValue", "anyValue"));
}

我想补充一点,如果失败案例是public boolean doSomething(String param1, String param2) { if (!"String1".equals(param1) && !"String2".equals(param1) && !"String3".equals(param1) { throw new IllegalArgumentException("param1 should be ..."); } ... // processing } 但是3个特定String,则测试单元无法涵盖所有​​失败案例:它会产生数百万种可能性。

在您的情况下,我认为使代码更健壮的最佳方法是使用有界类型作为枚举。您可以这样定义一个包含3个值的枚举,并提供一个枚举构造函数,其中String实际作为参数传递。

它可能看起来像:

String