Issue
I have a small Java 11 example with a JUnit 5 test that results in a pitest result of:
changed conditional boundary → SURVIVED
Main class:
public final class CheckerUtils
{
private CheckerUtils()
{
super();
}
public static int checkPort(final int port)
{
if (port < 0)
{
throw new IndexOutOfBoundsException("Port number out of range!");
}
return port;
}
}
Test class:
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;
import de.powerstat.security.CheckerUtils;
public final class CheckerUtilsTests
{
@Test
public void checkPortOk()
{
final int port = 1023;
final int resultPort = CheckerUtils.checkPort(port);
assertEquals(port, resultPort, "Port not as expected!");
}
@Test
public void checkPortNegative1()
{
final int port = -1;
assertThrows(IndexOutOfBoundsException.class, () ->
{
CheckerUtils.checkPort(port);
}
);
}
@Test
public void checkPortNegative2()
{
final int port = -1;
int resultPort = 0;
try
{
resultPort = CheckerUtils.checkPort(port);
}
catch (final IndexOutOfBoundsException e)
{
// ignore
}
assertEquals(0, resultPort, "Port is not 0");
}
}
From my point of view the mutation should not survive, because:
- checkPortOk() is the normal path for a legal value that is not negative
- checkPortNegative1() is the path for the negative value when noting is mutated an the exception is thrown.
- checkPortNegative2(): When nothing is mutated, the exception is thrown and resultPort is still 0 - so the assertion is ok here
- checkPortNegative2(): When the < 0 is mutated to < -1 or something lower, then no exception will be thrown, so resultPort will become -1 and the assert will fail (mutation killed)
- checkPortNegative2(): When the < 0 is mutated to < 1 or something higher, the same as under 3.
So my question is did I miss something here or is it a bug in pitest (1.4.9)?
Solution
As statet by @henry,adding the following test solves the issue:
@Test
public void checkPortOk2()
{
final int port = 0;
final int resultPort = CheckerUtils.checkPort(port);
assertEquals(port, resultPort, "Port not as expected!");
}
Solution
The conditional boundary mutation will mutate
if (port < 0)
To
if (port <= 0)
As none of the tests provide an input of 0 they are not able to distinguish the mutant from the unmutated program and the mutant will survive.
Adding a test case that describes the expected behaviour when port is 0 should kill the mutant.
Answered By - henry
Answer Checked By - David Marino (JavaFixing Volunteer)