突变在应该使用具有自动注入字段的方法时未被杀死

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

提问人:Madara's Ghost 提问时间:3/16/2015 最后编辑:Madara's Ghost 更新时间:10/28/2019 访问量:3009

问:

我有以下几点:

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 "";
    }
}

和以下测试:

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("");
    }
}

正如预期的那样,测试通过。当我通过 PIT 运行它时,我得到以下结果

33   1. removed call to my/package/SetProperty::setProperty → SURVIVED

第 #33 行在类代码中突出显示。

检查的测试如下:

  • my.package.UnsetPropertyTest.testCallsSetPropertyWithCorrectParameters(my.package.UnsetPropertyTest)(32 毫秒)
  • my.package.UnsetPropertyTest.testUnsetThrowsForIncorrectNumberOfParameters(my.package.UnsetPropertyTest)(3 毫秒)

现在:

  • 当我更改测试调用参数 () 时,测试失败。不出所料args
  • 当我更改断言()参数时,测试失败。不出所料。verify(setProperty).setProperty(...)
  • 当我手动注释掉第一个代码块中突出显示的函数调用时,测试失败。

为什么突变能存活下来?

我正在使用 Java 8、Mockito 1.9.5 和 PIT 1.1.4。

java spring-boot 突变测试 pitest

评论

0赞 henry 3/16/2015
UnsetPropertyTest 是否列在 html 报告的“测试已检查”部分中?
0赞 Madara's Ghost 3/16/2015
@henry是的。我已经使用列出的测试更新了我的问题。
0赞 henry 3/16/2015
班上的其他变种人是否如预期的那样被杀死?
0赞 Madara's Ghost 3/16/2015
@henry是的,该方法中还有另外两个突变被正确杀死。
0赞 henry 3/16/2015
您是否能够将其提炼为重现该问题的最小项目?

答:

1赞 drekbour 10/28/2019 #1

多年后,但似乎没有人提到(Spring)和(Mockito)是相互排斥的解决方案。你有多个生成的子类,所以 PIT 只是对正在发生的事情感到困惑。@Resource@InjectMocksUnsetProperty

评论

0赞 Madara's Ghost 10/28/2019
我不再能够测试你的答案(4.5 年是很长的时间),但希望面临同样问题的其他人会。