Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using junit @Rule, expectCause() and hamcrest matchers

I have a test:

@Rule public ExpectedException thrown = ExpectedException.none(); ... @Test public void testMethod() {     final String error = "error message";     Throwable expectedCause = new IllegalStateException(error);     thrown.expectCause(org.hamcrest.Matchers.<Throwable>equalTo(expectedCause));     someServiceThatTrowsException.foo(); } 

When run via mvn the test method, I'm getting the error:

java.lang.NoSuchMethodError: org.junit.rules.ExpectedException.expectCause(Lorg/hamcrest/Matcher;)V

Test compiles fine.

Please help me, cannot understand how to test the cause of the exception?

like image 962
Alexandr Avatar asked Mar 12 '14 08:03

Alexandr


People also ask

How do you use ExpectedException?

Usage. You have to add the ExpectedException rule to your test. This doesn't affect your existing tests (see throwsNothing() ). After specifiying the type of the expected exception your test is successful when such an exception is thrown and it fails if a different or no exception is thrown.


2 Answers

Try it this way:

@Rule public ExpectedException thrown = ExpectedException.none();  @Test public void testMethod() throws Throwable {     final String error = "error message";     Throwable expectedCause = new IllegalStateException(error);     thrown.expectCause(IsEqual.equalTo(expectedCause));     throw new RuntimeException(expectedCause); } 

Consider not to check against the cause by equals but by IsInstanceOf and / or comapring the exception message if necessary. Comparing the cause by equals check the stacktrace as well, which may be more than you would like to test / check. Like this for example:

@Rule public ExpectedException thrown = ExpectedException.none();  @Test public void testMethod() throws Throwable {     final String error = "error message";     thrown.expectCause(IsInstanceOf.<Throwable>instanceOf(IllegalStateException.class));     thrown.expectMessage(error);     throw new RuntimeException(new IllegalStateException(error)); } 
like image 165
Harmlezz Avatar answered Oct 09 '22 03:10

Harmlezz


A little bit more briefly with static imports and checking both the class and the message of the cause exception:

import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.hasProperty; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat;  @Test public void testThatThrowsNiceExceptionWithCauseAndMessages(){       expectedException.expect(RuntimeException.class );      expectedException.expectMessage("Exception message");                                                 expectedException.expectCause(allOf(instanceOf(IllegalStateException.class),                                         hasProperty("message", is("Cause message"))) );       throw new RuntimeException("Exception message", new IllegalStateException("Cause message")); } 

You could even use the hasProperty matcher to assert nested causes or to test the "getLocalizedMessage" method.

like image 23
borjab Avatar answered Oct 09 '22 02:10

borjab