我最近遇到了一个问题,当我使用错误的参数调用我的服务中的方法时。这导致了某种中断,所以我正在考虑将来如何防止这种情况发生。
假设我有以下方法:
public boolean doSomething(String param1, String param2);
我想验证每次调用此方法时(无论我的服务位于何处),param1
值都是特定的(例如String1
,String2
和{{1}这将是一个有效的参数值。
是否有任何技术/库/工具可以在单元测试中验证这一点?
更新:正如已接受的答案所示,这是单元测试不应涵盖的内容,因为单元测试用于行为测试。将来阻止错误调用的是使用String3
或仅使用简单的参数检查。
答案 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