Java 如何对void验证方法的两种情况进行单元测试?
我正在编写一个void-validate方法,如下所示:Java 如何对void验证方法的两种情况进行单元测试?,java,unit-testing,junit,Java,Unit Testing,Junit,我正在编写一个void-validate方法,如下所示: void validate(SomeObject someObject) { if (check someObject with constraints) { throw new SomeException(); } } 要对该方法进行单元测试,我想测试合法和非法输入: 对于非法输入,我使用(预期=SomeException.class) 我想知道当某个对象是合法的时候,我们如何测试这个案例 要测试so
void validate(SomeObject someObject) {
if (check someObject with constraints) {
throw new SomeException();
}
}
要对该方法进行单元测试,我想测试合法和非法输入:
- 对于非法输入,我使用(预期=SomeException.class)
- 我想知道当某个对象是合法的时候,我们如何测试这个案例
someObject
合法的情况,只需在try
块中调用validate
。如果引发异常,则测试失败。如果没有抛出异常,则让测试正常结束并通过,因为这是预期的行为
示例如下所示:
@Test
public void myTest() {
try {
validate(new SomeObject());
} catch (Exception e) {
fail("expected no exception, but one was thrown.");
}
}
要测试
someObject
合法的情况,只需在try
块中调用validate
。如果引发异常,则测试失败。如果没有抛出异常,则让测试正常结束并通过,因为这是预期的行为
示例如下所示:
@Test
public void myTest() {
try {
validate(new SomeObject());
} catch (Exception e) {
fail("expected no exception, but one was thrown.");
}
}
在这种情况下,合法意味着验证无例外地完成。要测试它,只需调用validate
@Test
public void testLegal() throws SomeException {
validator.validate(/* some legal object*/);
}
只有在验证期间引发异常时,此测试才会失败。在这种情况下,合法意味着验证在没有异常的情况下完成。要测试它,只需调用validate
@Test
public void testLegal() throws SomeException {
validator.validate(/* some legal object*/);
}
只有在验证期间引发异常时,此测试才会失败。第一个测试用例:
@Test
public void testOK() throws Exception {
validate(someObject);
// At Least 1 assertion
}
@Test(expected=SomeException.class)
public void testException() throws Exception {
try {
validate(someObject);
} catch(SomeException e) {
// At Least 1 assertion
throw e;
}
}
第二个测试用例:
@Test
public void testOK() throws Exception {
validate(someObject);
// At Least 1 assertion
}
@Test(expected=SomeException.class)
public void testException() throws Exception {
try {
validate(someObject);
} catch(SomeException e) {
// At Least 1 assertion
throw e;
}
}
在第二个测试用例中,如果没有抛出异常,测试将失败,因为它需要SommeException.class
至少1个断言是必需的,因为您必须验证抛出的异常是否与预期的异常相符。第一个测试用例:
@Test
public void testOK() throws Exception {
validate(someObject);
// At Least 1 assertion
}
@Test(expected=SomeException.class)
public void testException() throws Exception {
try {
validate(someObject);
} catch(SomeException e) {
// At Least 1 assertion
throw e;
}
}
第二个测试用例:
@Test
public void testOK() throws Exception {
validate(someObject);
// At Least 1 assertion
}
@Test(expected=SomeException.class)
public void testException() throws Exception {
try {
validate(someObject);
} catch(SomeException e) {
// At Least 1 assertion
throw e;
}
}
在第二个测试用例中,如果没有抛出异常,测试将失败,因为它需要SommeException.class
至少有1个断言是必需的,因为您必须验证抛出的异常是否与预期的异常相符。谢谢。你有一个例子吗?“对不起,我是JUnit的新手。”博元用一个例子编辑了我的答案。如果这有帮助,请记住向上投票并接受=]为什么要使用
try
块?如果引发异常,测试将已经失败。无需无故添加try
块。。。这只会让考试更难阅读。(你的测试主体的5行中有4行是没有意义的。)@JonSkeet我只是觉得它让你第一眼就更清楚地知道测试到底是为了什么。与保存行相比,我更喜欢可读性,但如果您在测试中添加注释/命名测试的方式明确表明测试是为了查看是否引发异常,我不会与您争论以不同的方式进行测试。谢谢。你有一个例子吗?“对不起,我是JUnit的新手。”博元用一个例子编辑了我的答案。如果这有帮助,请记住向上投票并接受=]为什么要使用try
块?如果引发异常,测试将已经失败。无需无故添加try
块。。。这只会让考试更难阅读。(你的测试主体的5行中有4行是没有意义的。)@JonSkeet我只是觉得它让你第一眼就更清楚地知道测试到底是为了什么。与保存行相比,我更喜欢可读性,但如果您在测试中添加注释/命名测试的方式明确表明测试是为了查看是否引发了异常,那么我不会与您争论以不同的方式进行此操作。…引发的异常正是您所期望的异常。
已经这样做了,不是吗?它只检查课堂,不检查留言。举例来说,如果代码中有两个路径抛出相同的异常,但消息不同,则必须进行两个不同的单元测试来断言消息,以确保异常已在应该抛出的位置抛出。捕获异常,做出一些断言,然后抛出异常,最后再次做出另一个断言(使用@Test(expected=…)
最终会降低测试的可读性,仅举一个小例子。为什么不在调用validate()后简单地编写失败(SomeException.class+“expected”)
?它将节省@Test(预期=…)
,抛出异常并简化读取。我不这么认为。对我来说,在try
中写入失败(…)
或在catch中写入抛出e
在可读性方面是相同的。但是@Test(预期=SomeException.class)
可以快速显示哪些测试引发异常,哪些测试“正常”测试用例。它更详细,并且有更多的间接读取。我不认为它在可读性方面可能是相同的。在你的例子中,注释中预期的异常没有那么重要,因为我们在测试代码中也看到异常捕获。对于更复杂的测试,不以这种方式编码的开发人员可能会花点时间确保理解异常逻辑断言。…抛出的异常正是您所期望的异常。
已经这样做了,不是吗?它只检查类,而不是消息。例如,如果在代码中有两个路径抛出相同的异常,但消息不同,则必须进行2次differents进行单元测试以断言消息,以确保异常已被抛出到应该抛出的位置。捕获异常,做出一些断言,然后抛出异常,最后再次做出另一个断言(使用@Test(预期=…)
最终降低了测试的可读性,仅举一个小例子。为什么不在调用validate()
后简单地编写失败(SomeException.class+“预期”)
?它将节省@test(预期=…)
,抛出异常并简化阅读。我不这么认为。对于我来说,在中写入失败(…)
尝试或写入