I have the following:
public class UnsetProperty extends Command {
@Resource
private SetProperty setProperty;
public String parse(String[] args) {
if (args.length != 4) {
throw new RuntimeException("Incorrect number of arguments. Expected 4. Got " + args.length);
}
String publisher = args[0];
String version = args[1];
String mode = args[2];
String property = args[3];
/*
* Unsetting a property is done by changing the current property to null.
* Technically, the old property doesn't get changed, a new one is inserted with
* a higher revision number, and it becomes the canonical one.
*/
setProperty.setProperty(publisher, version, mode, property, null, false);
return "";
}
}
and the following test:
public class UnsetPropertyTest extends CommandTest {
@Configuration
public static class Config {
@Bean(name = "mockSetProperty")
public SetProperty getSetProperty() {
return mock(SetProperty.class);
}
@Bean
public UnsetProperty getUnsetProperty() {
return new UnsetProperty();
}
}
@Resource
@InjectMocks
private UnsetProperty unsetProperty;
@Resource(name = "mockSetProperty")
private SetProperty setProperty;
// ... SNIP ...
@Test
public void testCallsSetPropertyWithCorrectParameters() throws SQLException, TaboolaException {
final String[] args = new String[]{"publisher", "version", "mode", "property"};
final String output = unsetProperty.parse(args);
verify(setProperty).setProperty("publisher", "version", "mode", "property", null, false);
// The above line should have killed the mutation!
verifyNoMoreInteractions(setProperty);
assertThat(output).isEqualTo("");
}
}
The test passes, as expected. When I run it through PIT I get the following result
33 1. removed call to my/package/SetProperty::setProperty → SURVIVED
Line #33 is highlighted in the class code.
The tests examined are as follows:
my.package.UnsetPropertyTest.testCallsSetPropertyWithCorrectParameters(my.package.UnsetPropertyTest)
(32 ms)my.package.UnsetPropertyTest.testUnsetThrowsForIncorrectNumberOfParameters(my.package.UnsetPropertyTest)
(3 ms)Now:
args
) the test fails. As expectedverify(setProperty).setProperty(...)
) arguments the test fails. As expected.Why does the mutation survive?
I'm using Java 8, Mockito 1.9.5 and PIT 1.1.4.
A mutation is killed if at least one test case fails when the test is repeated. If this does not happen, the test cases do not detect that the source code has been changed, or in other words: the test cases also consider a test object other than the original one as correct.
Mutation Coverage Mutation testing is a testing technique used to improve the adequacy of tests and identify defects in code. The idea is to change the production code dynamically and cause the tests to fail.
Advantages of Mutation Testing Mutation testing helps find weak programs in the code that are responsible for bugs. It is also helpful in finding weak test cases (test cases that are not able to kill mutants). It helps the development team to check the quality of the source code.
Our analyses suggest that developers using mutation testing write more tests, and actively improve their test suites with high quality tests such that fewer mutants remain.
Years later but no one seemed to mention that (Spring) @Resource
and (Mockito) @InjectMocks
are mutually exclusive solutions. You have multiple generated subclasses of UnsetProperty
in play so PIT is simply confused about what's going on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With