Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pit mutation - if ( x !=null ) return null else throw new RuntimeException

I have a method that returns a custom object

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

its unit test checks that the object returned by getTheObject() method is not null

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

and test passes.

When running mutation test with Pitest it shows one SURVIVED mutation which says something like this:

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

The question is what should our unit test look like to get rid of this issue, and KILL that mutation

like image 714
Toseef Zafar Avatar asked Mar 11 '19 14:03

Toseef Zafar


People also ask

How do mutation tests work?

Mutation testing, also known as code mutation testing, is a form of white box testing in which testers change specific components of an application's source code to ensure a software test suite will be able to detect the changes. Changes introduced to the software are intended to cause errors in the program.

What is void method call mutator?

The void method call mutator removes method calls to void methods. For example. public void someVoidMethod(int i) { // does something } public int foo() { int i = 5; someVoidMethod(i); return i; } will be mutated to. public void someVoidMethod(int i) { // does something } public int foo() { int i = 5; return i; }

Why is mutation testing good?

The purpose is to help the tester develop effective tests or locate weaknesses in the test data used for the program or in sections of the code that are seldom or never accessed during execution. Mutation testing is a form of white-box testing.


2 Answers

I cannot reproduce this problem (i.e. same mutation is correctly KILLED). I don't think your question includes enough context (other "pitest didn't work" SO questions seem to revolve around use of Spring and/or Mockito both of which also amend bytecode/make additional classes)

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

  • Gradle 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);
      }
    }
like image 144
drekbour Avatar answered Oct 02 '22 19:10

drekbour


It is "return value mutator" of PIT (when return type is Object) and it is going to replace non-null return values with null and throw a java.lang.RuntimeException if the unmutated method would return null.

i.e mutated code:

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

Above mutator is expecting that your Junit should fail but for Runtime exception reason. assertNotNull(getTheObject()) is just to check whether return object is null or not and there is no way to get Runtime exception just by checking object value.

To kill this mutator you can call any method of that object (e.g getter()). Now if you call any method over null object (which is return by above muted code) then you will get null pointer exception (i.e Runtime exception) and your Junit will fail for muted code.

Ans:

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

Or

assertNotNull(getTheObject().getterOfAnyField());
like image 37
srp Avatar answered Oct 02 '22 18:10

srp