我想知道我是否可以测试(使用JUnit)异常生成的特定消息被抛出而不仅仅是“是否”抛出异常。 例如,JunitTest.java代码实际上将通过测试,因为抛出了异常,但如果我还想测试异常生成的字符串是否等于:“测试异常:整数可能不是负数...” 这可能吗?
TestException.java
public class TestException extends Exception {
/**
* @param message informative message about the problem found
*/
public TestException (String message) {
super("Test Exception: " + message);
}
}
Test.java
public void function(Integer mustBePositive) throws TestException {
if (mustBePositive < 0) {
throw new TestException("Integer may not be negative..");
}
else {
mustBePositive = myNum
}
}
JunitTest.java
import org.junit.*;
public class JUnitTest {
@Test(expected = TestException.class)
public void functionTest() throws TestException {
function(-1);
}
}
答案 0 :(得分:8)
注意:我认为@Matthew's answer更胜一筹。
您可以使用以下结构 - 它测试是否抛出了正确的异常(TestException.class
)和消息是否符合预期。
@Test(expected = TestException.class)
public void test_function_negative() {
try {
function(-5);
} catch (TestException ex) {
assertEquals("Integer may not be negative..", ex.getMessage());
throw ex;
}
}
修改强>
为什么我重新抛出异常(在评论之后):下面的第一个测试通过而第二个测试没有通过。因此它增加了额外的验证层。现在,如果我在下面的代码中捕获了ExceptionB,则两个测试都将失败。
@Test
public void test1() throws ExceptionB {
try {
throw new ExceptionA();
} catch (ExceptionA e) {
assertEquals("message", e.getMessage());
}
}
@Test(expected=ExceptionB.class)
public void test2() throws ExceptionA {
try {
throw new ExceptionA();
} catch (ExceptionA e) {
assertEquals("message", e.getMessage());
throw e;
}
}
public class ExceptionA extends Exception{
@Override
public String getMessage() {
return "message";
}
}
public class ExceptionB extends ExceptionA{}
答案 1 :(得分:6)
您可以使用标准JUnit TestRule ExpectedException。这允许您测试抛出异常,并测试异常附带的消息。例如:
public static class HasExpectedException {
@Rule
public ExpectedException thrown= ExpectedException.none();
@Test
public void throwsNothing() {
// no exception expected, none thrown: passes.
}
@Test
public void throwsNullPointerException() {
thrown.expect(NullPointerException.class);
throw new NullPointerException();
}
@Test
public void throwsNullPointerExceptionWithMessage() {
thrown.expect(NullPointerException.class);
thrown.expectMessage("happened?");
thrown.expectMessage(startsWith("What"));
throw new NullPointerException("What happened?");
}
}
expectMessage()
接受String(消息的子字符串)或Matcher,因此您可以进行正则表达式检查等等。
答案 2 :(得分:2)
assertEquals("Test Exception: Integer may not be negative..", e.getMessage());
答案 3 :(得分:1)
我是这样做的:
@Test
public void functionTest() throws TestException {
try {
function(-1);
fail("This should have thrown an exception.");
} catch (TextException e) {
assertEquals("exception test produced an unexpected message", EXPECTED_TEXT, e.getMessage());
}
}
这可能并不优雅,但它易于理解并涵盖所有基础。免责声明 - 我没有编译它。
答案 4 :(得分:1)
其他人已经指出了你可以用来测试它的结构,但是我不会测试它本身的信息,因为这可能非常脆弱。
您应该创建一个自定义异常,获取所需的所有数据,并断言数据存在。如果您真的关心该消息,那么您可以单独对异常本身进行单元测试。
鉴于你的例子:
public void function(Integer mustBePositive) throws TestException {
if (mustBePositive < 0) {
throw new TestException("Integer may not be negative..");
}
else {
mustBePositive = myNum
}
你可以抛出一个NegativeNumberException。如果你真的想知道这个数字是什么,你可以修改你的代码,将其作为参数:
public void function(Integer mustBePositive) throws TestException {
if (mustBePositive < 0) {
throw new NegativeNumberException(mustBePositive);
}
else {
mustBePositive = myNum
}
然后在你的测试中:
@Test(expected = NegativeNumberException.class)
public void functionTest() throws TestException {
try {
function(-1);
} catch (NegativeNumberException nne) {
assertThat(nne.getNumber(), equalTo(-1));
}
}
您的异常现在可以生成消息,但它认为合适,并且对该输出的更改不会影响其余的测试代码
答案 5 :(得分:1)
catch-exception是为了支持这种情况:
import static com.googlecode.catchexception.CatchException.*;
public void testFunction() throws Exception {
verifyException(obj).function(-1);
assertEquals("Integer may not be negative..",
caughtException().getMessage());
}
答案 6 :(得分:-1)
import org.junit。 *;
公共类JUnitTest {
@Test
public void functionTest() throws TestException {
try {
function (-1);
fail("");
} catch (TestException e) {
if (!e.getMessage().equals("Integer may not be negative.."))
fail("");
}
}