我有一个java程序,它针对2种不同的场景抛出了2个不同消息的异常,我希望Junit测试用例检查这两个消息是否相等。举个例子 -
public void amethod() {
// do some processing
if(scenario1 == true) {
throw new MySystemException("An error occured due to case 1 being incorrect.");
}
else if(scenario2 == true) {
throw new MySystemException("An error occured as case 2 could not be found");
}
}
现在JUnit就像 -
public void testAMethod() {
// do something
assertEquals("Expected", "Actual");
}
据我了解,在上面的示例中,如果我使用Scenario1
异常消息,则在Scenario2
抛出异常时junit将失败,反之亦然。
我想知道在Junit中是否有任何其他方法可以使用这个test method
并检查两个测试通过的消息?
像OR
这样的东西,如果可能的话,提供这些预期消息的“预期”值
我希望我的查询足够清楚。
谢谢
更新
对于延迟回复感到抱歉,已经遇到了其他一些紧急事项
谢谢大家提出的非常好的建议,它现在帮助我更好地理解了。
最后,为了保持相当简单,我决定实施Don Roby建议的类似解决方案。因此创建了一个新的测试类,看起来像 -
public void testAMethodScenario1() {
// do the necessary
assertEquals("Expected Exception Message 1", "Actual");
}
public void testAMethodScenario2() {
// do the necessary
assertEquals("Expected Exception Message 2", "Actual");
}
再次感谢大家的回复。
答案 0 :(得分:5)
我认为您需要手动捕获异常(针对每个方案)并单独检查消息:
try {
// trigger scenario 1
fail("An exception should have been thrown here !");
} catch (MySystemException e1) {
assertEquals("Wrong error message", m1, e1.getMessage());
}
try {
// trigger scenario 2
fail("An exception should have been thrown here !");
} catch (MySystemException e2) {
assertEquals("Wrong error message", m2, e2.getMessage());
}
当然,您可以将这些场景定义为枚举常量,并简单地遍历它们并在循环中检查它们中的每一个,因为“复制/粘贴设计模式”在上面的代码中非常明显。 :)
答案 1 :(得分:2)
您似乎在这里问两件事,如何测试异常以及如何断言值与两个可能的预期值匹配。
要测试异常,您可以使用JUnit4注释:
@Test(expected=MySystemException.class)
public void testException() {
amethod();
}
或在测试中使用try-catch:
@Test
public void testException() {
try {
amethod();
fail("MySystemException expected");
}
catch (MySystemException e) {
// Success!
}
}
如果你只有一条消息,在try-catch版本中你可以断言你在catch块中使用AssertEquals
得到它。
最佳测试将针对您的两个方案进行单独测试,并期望正确的单个消息。事实上,更好的代码可能会对这两种情况有明显的例外。
但是,无论如何都需要一个比简单平等更复杂的断言,并且在Hamcrest匹配器中有一个优雅的解决方案。
在这种情况下使用它,您可以编写类似的内容(未经测试 - 完全不相信我的语法):
@Test
public void testException() {
try {
amethod();
fail("MySystemException expected");
}
catch (MySystemException e) {
String expectedMessage1 = "An error occured due to case 1 being incorrect.";
String expectedMessage2 = "An error occured as case 2 could not be found";
assertThat(e.getMessage(),
anyOf(equalTo(expectedMessage1), equalTo(expectedMessage2)));
}
}
答案 2 :(得分:1)
您能预测哪种情况会发生吗?如果是这样,Costi的答案是正确的。如果没有,因为有一些随机性或其他什么,你可以写:
@Test
public void testAmethodThrowsException() {
try {
amethod();
fail("amethod() should have thrown an exception");
}
catch (MySystemException e) {
String msg = e.getMessage();
assertTrue("bad message: " + msg, msg.equals("An error occured due to case 1 being incorrect.") || msg.equals("An error occured as case 2 could not be found"));
}
}
答案 3 :(得分:1)
方法抛出的声明的异常类型是其API的一部分。如果确实想要区分不同的故障模式,则应为每种故障模式声明不同的异常类型。
所以,像这样:
/**
* Do something.
* @throws MySystemException1 in case 1.
* @throws MySystemException2 if Foo not found.
*/
public void amethod() {
// do some processing
if(scenario1 == true) {
throw new MySystemException1("Case 1.");
}
else if(scenario2 == true) {
throw new MySystemException2("Foo not found");
}
}
答案 4 :(得分:0)
JUnit 4提供(Expected Exception.class)
@Test(expected= MySystemException.class) public void empty() {
// what ever you want
}
Google:有关更多信息的预期异常JUnit。
答案 5 :(得分:0)
JUnit4中的@Rule解决方案:
public class ExceptionRule implements MethodRule {
@Override
public Statement apply(final Statement base, final FrameworkMethod method, Object target) {
return new Statement() {
@Override
public void evaluate() throws Throwable {
try {
base.evaluate();
Assert.fail();
} catch (MySystemException e) {
if(scenario1)
assertEquals("Expected error message1", e1.getMessage();
if(scenario2)
assertEquals("Expected error message2",e1.getMessage();
}
}
};
}
}
在您的测试用例中,使用规则:
@Rule public ExceptionRule rule = new ExceptionRule();
答案 6 :(得分:0)
@Test
public void testAMethodScenario1() {
//given scenario 1
when(foo).amethod();
then(caughtException())
.isInstanceOf(MySystemException.class)
.hasMessage("An error occured due to case 1 being incorrect.");
}
@Test
public void testAMethodScenario2() {
//given scenario 2
when(foo).amethod();
then(caughtException())
.isInstanceOf(MySystemException.class)
.hasMessage("An error occured as case 2 could not be found");
}
com.googlecode.catch-exception:catch-exception:1.2.0
答案 7 :(得分:0)
使用@Rule更好的解决方案,您还可以声明异常和期望消息。
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Test
public void aMethod_Scenario1True_ThrowsException() {
expectedException.expect(MySystemException.class);
expectedExcepion.expectMessage("An error occured due to case 1 being incorrect.");
//when().thenReturn();
//handle the repositories, static methods and other sub methods, if needed
amethod();
}
@Rule是编写异常的更优雅的方法。