Mutation not killed when it should be with a method with an auto-injected field
Asked Answered
S

1

13

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:

  • When I change the test invoke parameters (args) the test fails. As expected
  • When I change the assertion (verify(setProperty).setProperty(...)) arguments the test fails. As expected.
  • When I manually comment out the function call highlighted in the first code block, the test fails.

Why does the mutation survive?

I'm using Java 8, Mockito 1.9.5 and PIT 1.1.4.

Sour answered 16/3, 2015 at 12:59 Comment(9)
Is UnsetPropertyTest listed in the "Test Examined" section of the html report?Iridissa
@Iridissa Yes. I've updated my question with the tests listed.Tredecillion
Are other mutants in the class killed as expected?Iridissa
@Iridissa yes, there are two other mutations in the method that are killed correctly.Tredecillion
Are you able to distil this down to a minimal project that reproduces the issue?Iridissa
@Iridissa This is about as basic as it gets. What are you missing?Tredecillion
Just need something runnable with dependencies, build file etc + to know the thing I'm looking at definitely reproduces it on your machine.Iridissa
I'm new to spring-boot, so bare with me; I don't see why your test would fail. It looks good to me. What do you mean when you say "killed the mutation"?Raama
What if you manually remove call to setProperty.setProperty(publisher, version, mode, property, null, false); and try to rut the tests? Does it fail as you expect or does it pass?Motherofpearl
K
1

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.

Kingwood answered 27/10, 2019 at 21:41 Comment(1)
I am no longer in a position to test your answer (4.5 years is a long time), but hopefully someone else facing the same problem will.Tredecillion

© 2022 - 2024 — McMap. All rights reserved.