Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Junit 4 ExpectedException.expectMessage should fail the test, and it doesn't

I have the following class:

public class MyClassTest {
@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void testMyMethod() throws Exception {
    // Test 1
    String[] args = ...;
    MyClass.myMethod(args);

    // Test 2
    thrown.expect(InvalidParamException.class);
    thrown.expectMessage("exceptionString 1");
    args = ...;
    MyClass.myMethod(args);

    // test 3
    thrown.expect(InvalidParamException.class);
    thrown.expectMessage("exceptionString 2");
    args = ...;
    MyClass.myMethod(args);
}

the problem is that the expectMessage in Test 2 is false, for the sake of discussion the actual expected message is exceptionString 3, and yet the test doesn't fail, although the expected message differs from the actual message. It gets weirder - if I provide the expectMessage a gibberish message such as "fdsfsdfsdfsdfsdfsdthe" - then the test does fail:

java.lang.AssertionError: Expected: (an instance of InvalidParamException and exception with message a string containing "fdsfsdfsdfsdfsdfsdthe") but: exception with message a string containing "fdsfsdfsdfsdfsdfsdthe" message was "exceptionMessage3"

And that's the expected behavior - but when I change the exceptionMessage3 just a little bit, letter or two, even sending an empty string - the the test does not fail at all.

Am I missing something?

like image 987
SockworkOrange Avatar asked Nov 28 '25 06:11

SockworkOrange


1 Answers

ExpectedException only holds 1 expected exception.

You can't reuse it like this. Either:

  1. Split up your test case into 3 separate test cases;
  2. Have 3 ExpectedException instances;
  3. Use plain old try/catch;
  4. Use assertThrows (or expectThrows) if you're using a recent-enough version of Java (8+) and JUnit that supports it.
like image 50
Andy Turner Avatar answered Nov 30 '25 18:11

Andy Turner