1

I'm writing a Stack class using the Test Driven Design concept.

In the setUp() method my stack is created with 0 elements like this

Stack stack = new Stack();

This is my attempted test to catch the StackEmptyException which would be raised when top is immediately called after setUp().

@Test
public final void testTopIsEmpty() throws StackEmptyException
{
  StackEmptyException thrown = null;
  try
  {
    stack.top();
  }
  catch (StackEmptyException caught)
  {
    thrown = caught;
  }
  assertThat(thrown, is(instanceOf(StackEmptyException.class)));
}

My problem is in the last line. I don't understand why my code doesn't work!

Adam
  • 43,763
  • 16
  • 104
  • 144
Danny Rancher
  • 1,923
  • 3
  • 24
  • 43

2 Answers2

3

ExpectedException can be used to verify that an exception is thrown. The check can be in the middle of a method to make sure earlier method calls don't accidentally throw the same exception.

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void testTopIsEmpty() throws StackEmptyException {
    thrown.expect(StackEmptyException.class);
    stack.top();
}
fgb
  • 18,439
  • 2
  • 38
  • 52
2

The correct way to test for an exception in JUnit is:

@Test(expected = StackEmptyException.class)
public final void testTopIsEmpty() throws Exception
{
    stack.top();
}
Adam
  • 43,763
  • 16
  • 104
  • 144
  • I dislike this method of testing for exceptions because in a larger test (with more than one statement), the test merely states if an exception has occurred. With my logic, I can use the throw/catch block to explicitly learn if and from where the exception has been raised. Please understand while I wait for another answer. – Danny Rancher Oct 22 '12 at 23:02
  • Ok, try using `assertTrue(thrown instanceOf StackEmptyException.class)` and change the type of thrown to just `Exception`. What happens when you run it? – Adam Oct 22 '12 at 23:06
  • @DannyRancher You probably shouldn't have those larger tests to begin with. Maybe you could ask a new question asking how to test for your specific use case? – millimoose Oct 22 '12 at 23:17
  • One of ways. Not the only one, not the best IMO. I much prefer the `@Rule public ExpectedException thrown = ExpectedException.none();` way. For why - Szczepan, Mockito creator, put it greatly in words [in his blog posts](http://monkeyisland.pl/2010/07/26/expected-exception-in-tests/) – LAFK 4Monica_banAI_modStrike Oct 28 '12 at 20:44