简体   繁体   中英

Correct way to JUnit test divide() method

I've got this simple method:

public int divide(int a, int b) throws ArithmeticException {
        if (b == 0) {
            throw new ArithmeticException("Division by 0");
        } else {
            return a / b;
        }
    }

and I'd like to JUnit test it.

I've done as follows:

@Test(expected = ArithmeticException.class) // Expected this exc
    public void testDivideWhenDivisorIsZero() {
        int result = c.divide(1, 0);
    }

which "returns" a green bar line ("tests finished successfully").

  • Is this a correct way to JUnit test this method or should I have put a try-catch clause in that test?

EDIT

Would this JUnit test be equivalent with the following?

@Test
    public void testDivideWhenDivisorIsZero() {
        try{
            c.divide(1, 0);
            fail("Expected ArithmeticException");
        } catch(ArithmeticException e) {

        }
    }

Your test looks correct, and you should not use try..catch block in unit test. there are many ways, one of them is yours. But for your method I would like to use:

try {
    return a / b;
} catch (ArithmeticException e) {
    throw new ArithmeticException("Division by 0");
}

Let the exception be thrown, and catch it. it is more clean than checking the value before any action(which that case can be rare to happen)

The way you did this seems fine to me.

It should fit your need in this case. Nonetheless I personally prefering to do it with a try-catch-block. Which as you proposed are pretty equivalent. I think you've a few advantages if you do with the try-catch-block.

First of all, you can assert, if the errormessage of the thrown exception is actually as you've excepted and in addition you can be sure, that the exception actually happened during your method-under-test and not during your init-logic. To get this a little bit clearer:

public int divide(int a, int b) throws ArithmeticException {
        if (b == 0) {
            throw new ArithmeticException("Division by 0");
        } else if(a<b){
            //I know, that this condition is pretty senseless. It's for demonstration only.
            throw new ArithmeticException("a is smaller than b");
        } else{
            return a / b;
        }
    }

Then you can test your method like this and you can be sure, that the correct Exception was thrown:

@Test
    public void testDivideWhenDivisorIsZero() {
        try{
            c.divide(1, 2);
            fail("Expected ArithmeticException");
        } catch(Exception e) {
            if(e instanceof ArithmeticException){
               Assert.assertTrue(e.getMessage().equals("a is smaller than b"));
            }else{
               fail("The wrong Exception was thrown" + e.toString())
            }
        } 
    }

But as I said your attempt fits absolutely the needs.

Production code: Neither catching nor declaring the exception is necessary, and I recommend avoiding both.

public static int divide(int a, int b) {
    return a / b;
}

If you want to communicate to your API user that an ArithmeticException can be thrown, then you should do it in the javadoc.

Testcode: JUnit5 made asserting exceptions much more easy.

@Test
void divide_whenDenominatorIsZero_shouldThrow() {
    assertThrows(ArithmeticException.class, () -> divide(1, 0));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM