0

What do you do with methods that throw exceptions in jUnit tests? As you see the addAnswer method in the Question class may throw a exception. In the shouldFailifTwoAnswerAreCorrect method I want to check if the exception is thrown but in the shouldAddAnswersToQuestion

Should I add throws MultipleAnswersAreCorrectException from the private addAnswerToQuestion method and try/catch in the shouldAddAnswersToQuestion or throw it in that method too?

What do you do when methods throw exception(s) in tests?

public class QuestionTest {

    private Question question;

    @Before
    public void setUp() throws Exception {
        question = new Question("How many wheels are there on a car?", "car.png");
    }

    @Test
    public void shouldAddAnswersToQuestion() {

        addAnswerToQuestion(new Answer("It is 3", false));
        addAnswerToQuestion(new Answer("It is 4", true));
        addAnswerToQuestion(new Answer("It is 5", false));
        addAnswerToQuestion(new Answer("It is 6", false));

        assertEquals(4, question.getAnswers().size());
    }

    @Test(expected = MultipleAnswersAreCorrectException.class)
    public void shouldFailIfTwoAnswersAreCorrect() {

        addAnswerToQuestion(new Answer("It is 3", false));
        addAnswerToQuestion(new Answer("It is 4", true));
        addAnswerToQuestion(new Answer("It is 5", true));
        addAnswerToQuestion(new Answer("It is 6", false));
    }

    private void addAnswerToQuestion(Answer answer) {
        question.addAnswer(answer);
    }
}

Method in Question class

public void addAnswer(Answer answer) throws MultipleAnswersAreCorrectException {

    boolean correctAnswerAdded = false;

    for (Answer element : answers) {
        if (element.getCorrect()) {
            correctAnswerAdded = true;
        }
    }

    if (correctAnswerAdded) {
        throw new MultipleAnswersAreCorrectException();
    } else {
        answers.add(answer);    
    }
}
unholysampler
  • 17,141
  • 7
  • 47
  • 64
LuckyLuke
  • 47,771
  • 85
  • 270
  • 434
  • possible duplicate of [How do you assert that a certain exception is thrown in JUnit 4 tests?](http://stackoverflow.com/questions/156503/how-do-you-assert-that-a-certain-exception-is-thrown-in-junit-4-tests) – Nateowami Jul 29 '14 at 06:47

2 Answers2

7

You have to add throws declaration to addAnswerToQuestion and then either try/catch the exception or use expected attribute or @Test:

@Test(expected=IOException.class)
public void test() {
    // test that should throw IOException to succeed.
}
unholysampler
  • 17,141
  • 7
  • 47
  • 64
AlexR
  • 114,158
  • 16
  • 130
  • 208
  • So you don't do anything other than normal in the try/catch in a jUnit test? What do you do if for a strange reason throws an exception (even though it shouldn't in this method)? Do you write .printStackTrace() etc? – LuckyLuke Feb 19 '12 at 15:52
  • Exactly. So just don't catch then you get the stack trace to start debugging. – Hauke Ingmar Schmidt Feb 19 '12 at 16:06
  • @his A little trouble understanding what you meant. Do you mean I should not do anything in catch or that I should print the stacktrace? – LuckyLuke Feb 19 '12 at 16:11
0

In shouldAddAnswersToQuestion test if you are not expecting MultipleAnswersAreCorrectException then you can surround the block in a try/catch and write an assert fail condition e.g.

    @Test
public void shouldAddAnswersToQuestion() {
  try{
       addAnswerToQuestion(new Answer("It is 3", false));
       addAnswerToQuestion(new Answer("It is 4", true));
       addAnswerToQuestion(new Answer("It is 5", false));
       addAnswerToQuestion(new Answer("It is 6", false));
       assertEquals(4, question.getAnswers().size());
   }catch(MultipleAnswersAreCorrectException  e){
     Assert.assertFail("Some self explainable failure statement");
   }
}

I think its always better to make the test fail, Instead of throwing the exception from the test, because all the test should fail for an assertin failure and not because of exception.

Sajan Chandran
  • 11,287
  • 3
  • 29
  • 38
  • 1
    Absolutely not! This way all the information why the test failed is completely lost. Otherwise you just could look into the stack trace. Test frameworks know how to handle methods that throw exceptions. – Hauke Ingmar Schmidt Feb 19 '12 at 16:05
  • @his This exception is a user defined exception so there is nothing to debug, we should know when this exception will be raised, so there is no point to printing the stacktrace. Test should have only 2 outputs either pass or fail. – Sajan Chandran Feb 19 '12 at 17:54
  • You should *not* print the stacktrace. An unexpected exception *is* a fail. – Hauke Ingmar Schmidt Feb 19 '12 at 18:01
  • Two things we know that this exception can happen, second thing exception is different from test assertion failure – Sajan Chandran Feb 19 '12 at 18:12
  • 1
    Should this exception happen in this test? Add it as expected exception. Should it not happen? Test fails. It may happen? You are not writing a unit test. – Hauke Ingmar Schmidt Feb 19 '12 at 18:19