5

我有一个返回自定义对象的方法

public MyObject getTheObject(){
  ...
  return muObject;
}

它的单元测试检查getTheObject()方法返回的对象不为空

@Test
public void testGetTheObject(){
  ...
  assertNotNull(actualObject);
}

并且测试通过。

当使用 Pitest运行突变测试时,它会显示一个SURVIVED突变,如下所示:

mutated returned of Object for value for ..../getTheObject to ( if ( x!= null ) null else throw new RuntimeException )

问题是我们的单元测试应该是什么样子才能摆脱这个问题和KILL那个突变

4

2 回答 2

5

我无法重现此问题(即相同的突变被正确杀死)。我认为您的问题没有包含足够的上下文(其他“pitest 不起作用”所以问题似乎围绕着 Spring 和/或 Mockito 的使用,这两者都还修改了字节码/制作了额外的类)

https://stackoverflow.com/help/minimal-reproducible-example

  • 摇篮 5.2.1
  • JUnit 5
  • Pitest 1.4.5
    public class SO55104467 {
      public static class MyObject {}
      private final MyObject muObject = new MyObject();
      public MyObject getTheObject(){
        return muObject;
      }
    }

    class SO55104467Test {
      private SO55104467 sut = new SO55104467();
      @Test
      public void testGetTheObject(){
        SO55104467.MyObject actualObject = sut.getTheObject();
        assertNotNull(actualObject);
      }
    }
于 2019-10-28T11:58:26.857 回答
4

它是 PIT 的“返回值变异器”(当返回类型为 Object 时),它将用 null 替换非 null 返回值,如果未变异的方法将返回 null,则抛出 java.lang.RuntimeException。

即变异代码:

public MyObject getTheObject(){
  ...
  return null;
}

上面的 mutator 期望您的 Junit 应该失败,但由于运行时异常原因。 assertNotNull(getTheObject())只是检查返回对象是否为空,仅通过检查对象值是无法获得运行时异常的。

要杀死这个 mutator,您可以调用该对象的任何方法(例如 getter())。现在,如果您在空对象上调用任何方法(由上述静音代码返回),那么您将获得空指针异常(即Runtime exception)并且您的 Junit 将因静音代码而失败。

答:

assertThat(getTheObject().getterOfAnyField(),is(expectedValue));

或者

assertNotNull(getTheObject().getterOfAnyField());
于 2019-06-06T13:18:34.743 回答