我一直在研究Java应用程序,我必须使用JUnit进行测试。我正在学习它。到目前为止,我发现它很有用,特别是与Eclipse JUnit插件结合使用时。
在玩了一下之后,我开发了一种一致的方法来为没有返回值的函数构建单元测试。我想在这里分享并请其他人发表评论。您是否有任何建议的改进或替代方法来实现相同的目标?
常用回报值
首先,有一个枚举用于存储代表测试结果的值。
public enum UnitTestReturnValues
{
noException,
unexpectedException
// etc...
}
广义测试
假设正在编写单元测试:
public class SomeClass
{
public void targetFunction (int x, int y)
{
// ...
}
}
将创建JUnit测试类:
import junit.framework.TestCase;
public class TestSomeClass extends TestCase
{
// ...
}
在这个类中,我创建了一个函数,用于每次调用正在测试的目标函数。它捕获所有异常并根据结果返回消息。例如:
public class TestSomeClass extends TestCase
{
private UnitTestReturnValues callTargetFunction (int x, int y)
{
UnitTestReturnValues outcome = UnitTestReturnValues.noException;
SomeClass testObj = new SomeClass ();
try
{
testObj.targetFunction (x, y);
}
catch (Exception e)
{
UnitTestReturnValues.unexpectedException;
}
return outcome;
}
}
JUnit测试
JUnit调用的函数在函数名称中以小写“test”开头,并且在第一次失败的断言时失败。要在上面的targetFunction上运行多个测试,它将被写为:
public class TestSomeClass extends TestCase
{
public void testTargetFunctionNegatives ()
{
assertEquals (
callTargetFunction (-1, -1),
UnitTestReturnValues.noException);
}
public void testTargetFunctionZeros ()
{
assertEquals (
callTargetFunction (0, 0),
UnitTestReturnValues.noException);
}
// and so on...
}
如果您有任何建议或改进,请与我们联系。请记住,我正在学习如何使用JUnit,所以我确信现有的工具可以使这个过程更容易。谢谢!
答案 0 :(得分:3)
确实,如果您正在使用JUnit 3,并且您正在测试是否在方法中抛出或抛出特定异常,则需要使用类似上面定义的try-catch模式。
然而:
1)我认为测试一个带有void返回值的方法然后检查异常还有很多:你的方法是否正确调用(可能是模拟的)依赖项;当使用不同的上下文或不同的依赖关系集等初始化类时,它的行为会有所不同。通过将所有调用包装到该方法,您很难更改测试的其他方面。
我也普遍反对添加代码并增加复杂性,如果可以避免的话;我不认为在检查异常时必须在给定的测试中放置try / catch是一种负担。
2)切换到JUnit 4!它可以很容易地检查预期的异常:
@Test(expected=IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}
答案 1 :(得分:2)
如果您有可能,则应升级到JUnit 4.x。
然后你的第一个例子可以改写为:
@Test(expected=RuntimeException.class)
public void testTargetFunction() {
testObj.targetFunction (x, y);
}
这里的优点是您可以删除private UnitTestReturnValues callTargetFunction (int x, int y)
方法并使用JUnit内置的支持来预期异常。
您还应该测试特定的例外情况。
答案 2 :(得分:1)
看起来你重新实现了大部分JUnit :)一般来说你不需要这样做。您只需调用要调用的函数并比较结果即可。如果它抛出异常,JUnit将为您捕获并且未通过测试。如果您期望发生异常,则可以使用显式注释(如果使用的是JUnit 4),也可以使用以下模式:
public void testThrows()
{
try {
obj.DoSth(); //this should throw MyException
assertFail("Expected exception");
} catch (MyException e) {
//assert the message etc
}
}
再次,如果obj.DoSth()抛出一个不同的异常,JUnit将无法通过测试。
总而言之,我担心我的方法过于复杂,抱歉。
答案 3 :(得分:0)
public void testTargetFunctionSomeValue() {
int someValue = 0;
callTargetFunction(someValue, someValue);
assertTrue(verifyTargetFunction(someValue, someValue));
}
public boolean verifyTargetFucntion(int someValue, int someValue) {
// verify that execution of targetFunction made expected changes.
. . . . .
}
如果调用targetFunction进行了预期的更改,那么和verifyTargetFunction将进行实际检查 - 让我们通过返回true或false来说明数据库表。
希望有所帮助。
干杯, 马库斯