Reputation: 2050
How to implement a testing method with different results and exceptions?
I simplified the code to understanding:
public double someCalc(double a, double b, double c) throws ALessThanZeroException, BIsZeroException{
if (a < 0){
throw new ALessThanZeroException();
}
if (b == 0){
throw new BIsZeroException();
}
return a*b*c;
}
So, how can you validate this method in jUnit
? Do I need to create 3 different tests, or can I combine "parameterized" and "exception expected" methods in this case?
Upvotes: 0
Views: 135
Reputation: 2955
You could use a parametrized test to it, but honestly, create 3 separate tests. It's much clearer and it follows a rule "give a test exactly one reason to fail".
So:
@Test(expected = ALessThanZeroException.class)
public void shouldThrowALessThanZero_WhenIncorrectA() {
//... your logic here
}
@Test(expected = BIsZeroException.class)
public void..... and so on
There is also another approach with using JUnit's @Rule
:
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
// ...
@Test
public void shouldThrowALessThanZero_WhenIncorrectA() {
exceptionRule.expect(ALessThanZeroException.class);
exceptionRule.expectMessage("A should be greater than 0.");
// ...
}
For the parametrized test, I would use it if I wanted to test my code against different inputs and check outputs. It seems similar to your question, but in your case you're testing specific logic, some corner cases. Don't mix it with "regular" cases.
Upvotes: 2
Reputation: 844
If you have custom runtime exceptions (for example an exception containing a status code or reason) you might want to assert the code/reason as well. In this case in Junit 5 you can do the following:
@Test
void someTestMethod(){
// First case
YourExceptionType exception = assertThrows(YourExceptionType.class, () -> myService.methodToTest(param1, param2));
assertThat(exception.getCode(), is(1001));
// Second case
YourExceptionType exception = assertThrows(YourExceptionType.class, () -> myService.methodToTest(param3, param4));
assertThat(exception.getCode(), is(1002));
}
As you can see it is not necessary to do one test/exception anymore...
Upvotes: 1
Reputation: 26926
You need to create one method for each possible situation. Because you have 3 possible exit point from your method you need at least 3 tests:
// Check if a is less than 0
@Test(expected = ALessThanZeroException.class)
public void throwsALessThanZero_WhenALessZero() {
yourclass.someCalc(-1.0, 2.0, 30.0);
}
// Check if a is not less than 0 and b is 0
@Test(expected = BIsZeroException.class)
public void throwsBIsZero_WhenAIsNotLessZeroAndBIsZero() {
yourClass.someCalc(2.0, 0.0., 3.4);
}
// Test normal situation
@Test
public void calculate_WhenAIsNotLessZeroAndBIsNotZero() {
double a = 2.0;
double b = 1.0;
double c = 3.0;
double res = yourClass.someCalc(a, b, c);
assertEquals(res, a * b * c);
}
Upvotes: 1