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

2

5

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

Calvities answered 11/3, 2019 at 14:47 Comment(8)
I have no idea what SURVIVED and KILL mean in this context. Please show us the code that produces the output that you're asking about. There's no way we can guess what's going on just from some random error message.Ithyphallic
What is x in this context?Verdun
what pit documentation says x is the object that I am returning in the getTheObject() method. SURVIVED means if pit mutates (changes) something in my code, my unit test still passes, KILL means the pit mutations can not get my unit test pass.Calvities
Ton answer your question, we need to know which mutator did not kill one of its mutations. Look in the maven log after lines like this: > org.pitest.mutationtest.engine.gregor.mutators.ReturnValsMutator >> Generated 2 Killed 1 (50%) > KILLED 1 SURVIVED 0 TIMED_OUT 0 NON_VIABLE 0 > MEMORY_ERROR 0 NOT_STARTED 0 STARTED 0 RUN_ERROR 0 > NO_COVERAGE 1 Amateurism
I think its RETURN_VALS_MUTATOR, I am using IntellijIdea and running it through a plugin which generates HTML reports.Calvities
Do you could make the whole example available?Micahmicawber
Toseef: Could you please respond to the comments for clarification and try to improve this question - or, if you found a solution, post it as an answer yourself? I have added a bounty to your question, because another user has posted a very similar question which got closed as duplicate of your question, but it seems that your question actually lacks information to be answerable in a satisfying way.Laomedon
Max: apologies, I put the question long time ago, and have forgotten what I ended up with to KILL that mutation.Calvities
T
5

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);
      }
    }
Triplicate answered 28/10, 2019 at 11:58 Comment(1)
Thanks drekbour, I cant remember where I ended up with that but thanks for help.Calvities
M
4

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());
Messily answered 6/6, 2019 at 13:18 Comment(3)
Can you try to explain the answer a bit better? I for one do not see the connection between assertThat(mutationTestService.getClassAObj(10).getA(),is(10)); and getTheObject(){return null;}. Also I don't understand why assertNotNull would not be sufficient to kill the mutator. Since the mutator returns null, assertNotNull should fail the unit test. What am I missing? Thanks!Laomedon
@MaxVollmer I have improved my answer little bit. I hope it will be helpful for you.Return value mutator of pit is expecting test case should fail but for Runtime exception reason. ThanksMessily
Author of pitest here. Although in general you probably want tests that do more than assert that a return value is not null, a simple assertNotNull should be enough to kill this mutation, and this answer is therefore not correct.Garrett

© 2022 - 2024 — McMap. All rights reserved.