JUNIT 测试无效方法

我有一个 Java 类充满了 void 方法,我想做一些单元测试,以获得最大的代码覆盖率。

例如,我有这个方法:

protected static void checkifValidElements(int arg1,  int arg2) {
method1(arg1);
method2(arg1);
method3(arg1, arg2);
method4(arg1, arg2);
method5(arg1);
method6(arg2);
method7();
}

因为我翻译了代码以便更好地理解,所以它的名字很糟糕。每个方法都验证参数是否以某种方式有效并且写得很好。

例如:

private static void method1(arg1) {
if (arg1.indexOf("$") == -1) {


//Add an error message
ErrorFile.errorMessages.add("There is a dollar sign in the specified parameter");
}
}

我的单元测试很好地覆盖了小方法,因为我让它们检查 ErrorFile 是否包含错误消息,但是我不知道如何测试我的方法 checkIfValidElements,它什么也不返回或什么也不更改。当我使用 Maven 运行代码覆盖率时,它告诉我单元测试不覆盖类的这一部分。

我看到的唯一方法是改变这个方法来返回一个 int 或者 bollean 值,像这样:

protected static int checkifValidElements(int arg1,  int arg2) {
method1(arg1);
method2(arg1);
method3(arg1, arg2);
method4(arg1, arg2);
method5(arg1);
method6(arg2);
method7();
return 0;
}

使用这种方法,我可以做一个断言等于,但对我来说,这样做似乎是徒劳的。问题是,我有两个类是这样设计的,它降低了我的单元测试覆盖率% 。

277670 次浏览

我想做一些单元测试,以获得最大的代码覆盖率

代码覆盖率永远不应该是编写单元测试的 目标。您应该编写单元测试来证明您的代码是正确的,或者帮助您更好地设计它,或者帮助其他人理解代码的用途。

但是我不知道如何测试我的方法 checkIfValidElements,它什么也不返回或什么也不改变。

那么您可能应该进行一些测试,在这些测试之间检查所有7个方法是否被适当地调用——使用无效的参数和有效的参数,每次检查 ErrorFile的结果。

例如,假设有人删除了对以下内容的调用:

method4(arg1, arg2);

或者不小心改变了论点顺序:

method4(arg2, arg1);

你如何注意到这些问题? 从这里开始,设计测试来证明它。

您仍然可以通过断言 void 方法具有适当的副作用来对其进行单元测试。在 method1示例中,您的单元测试可能类似于:

public void checkIfValidElementsWithDollarSign() {
checkIfValidElement("$",19);
assert ErrorFile.errorMessages.contains("There is a dollar sign in the specified parameter");
}

我认为你应该避免写副作用的方法。从您的方法返回 true 或 false,您可以在单元测试中检查这些方法。

如果您的方法没有副作用,并且不返回任何内容,那么它就不会执行任何操作。

如果您的方法执行了一些计算并返回了该计算的结果,那么显然可以断言返回的结果是正确的。

如果您的代码没有返回任何内容,但是确实有副作用,您可以调用该代码,然后断言已经发生了正确的副作用。副作用是什么将决定你如何进行检查。

在您的示例中,您正在从不返回的函数调用静态方法,除非您能够检查所有这些静态方法的结果是否正确,否则这会使问题变得棘手。从测试的角度来看,一种更好的方法是在调用方法的对象中注入实际的对象。然后可以使用类似 EasyMock 或 Mockito 的工具在单元测试中创建一个 Mock 对象,并将模拟对象注入到类中。然后,使用 Mock Object 可以断言以正确的值和正确的顺序调用了正确的函数。

例如:

private ErrorFile errorFile;


public void setErrorFile(ErrorFile errorFile) {
this.errorFile = errorFile;
}


private void method1(arg1) {
if (arg1.indexOf("$") == -1) {


//Add an error message
errorFile.addErrorMessage("There is a dollar sign in the specified parameter");
}
}

然后在你的测试中你可以写:

public void testMethod1() {
ErrorFile errorFile = EasyMock.createMock(ErrorFile.class);
errorFile.addErrorMessage("There is a dollar sign in the specified parameter");
EasyMock.expectLastCall(errorFile);
EasyMock.replay(errorFile);


ClassToTest classToTest = new ClassToTest();
classToTest.setErrorFile(errorFile);
classToTest.method1("a$b");


EasyMock.verify(errorFile); // This will fail the test if the required addErrorMessage call didn't happen
}

如果你的方法是 void 的并且你想检查一个异常,你可以使用 expected: Https://weblogs.java.net/blog/johnsmart/archive/2009/09/27/testing-exceptions-junit-47

你可以学习一些叫做“嘲笑”的东西,例如,你可以用它来检查: 一个函数被调用 一个函数叫做 x 次 一个函数被调用了至少 x 次 - 调用了一个带有特定参数集的函数。 例如,在您的示例中,您可以使用 mock 来检查 method3是否被调用过一次,无论您传递的是 arg1还是 arg2。

看看这些: Https://code.google.com/p/mockito/ Https://code.google.com/p/powermock/

如果可能的话,您可以将方法 method1(arg1)... method7() 受到保护而不是 二等兵,这样它们就可以从同一个包中的测试类中访问。然后,您可以分别测试所有这些方法。