-1

I am currently working on implementing a unit test for our Exit Code Manager that were implemented using static methods. The problem that I encounter is how can I mock the executeExit, which calls System.exit(), method so that it would not terminate all the test.

I tried spying on the SampleClass however it still continue on exiting the program whenever I run the test. Another solution that I try is to mock the whole class and use the doCallRealMethod for the method under test. However, this solution it faulty because (1) class under test are not undergoing code coverage, and (2) it is somehow testing the mocked class instead of the real class under test. I also tried mocking the System.class but it is also not working.

All kinds of help are pretty much appreciated. THANKS!

Below is a sample code similar to our method structure.

public class SampleClass{

    public static void methodA(){
        //do something here
        executeExit();

    public static void executeExit(){
        //doing some stuff
        System.exit(exitCode);
    }
}

Below is a sample code of how I run my test:

@RunWith(PowerMockRunner.class)
@PrepareForTest(SampleClass)
public class SampleClassTest {

    @Test
    public void testMethodA(){
        PowerMockito.spy(SampleClass.class);
        PowerMockito.doNothing().when(SampleClass.class,"executeExit");

        SampleClass.methodA();
    }
}
Vaanz
  • 175
  • 1
  • 2
  • 14
  • static method access makes your code (using this static methods) inflexible. Difficulties in writing tests is a clear sign of that. Using PowerMock is a surrender to bad design. – Timothy Truckle May 30 '17 at 10:49
  • https://stackoverflow.com/questions/44253748/error-in-junit-while-mocking/44254025#44254025 check this answer here. There is an example how to mock static method. Furthermore you even are able to mock System.exit or better said: You can verify it – kism3t May 30 '17 at 10:59

1 Answers1

1

I would test your code like this:

import org.junit.Rule;
import org.junit.Test;
import org.junit.contrib.java.lang.system.ExpectedSystemExit;
import org.junit.runner.RunWith;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
public class SampleClassTest {

    @Rule
    ExpectedSystemExit exit = ExpectedSystemExit.none();

    @Test
    public void testMethodA() {

        exit.expectSystemExitWithStatus(-1);
        SampleClass.methodA();
    }
}

You need following dependency

<dependency>
    <groupId>com.github.stefanbirkner</groupId>
    <artifactId>system-rules</artifactId>
    <version>1.16.1</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>junit</groupId>
            <artifactId>junit-dep</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Or if you do not want to import that dependency you can do it like:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ SampleClass.class })
public class SampleClassTest {


    @Test
    public void testMethodA() {

        PowerMockito.spy(SampleClass.class);
        PowerMockito.doNothing().when(SampleClass.class);
        SampleClass.executeExit();

        SampleClass.methodA();

        PowerMockito.verifyStatic();
        SampleClass.executeExit();

    }
}
kism3t
  • 1,343
  • 1
  • 14
  • 33
  • The second solution is my prefer way, but there are some issues with the code coverage. It is resulting to a 0% line coverage. – Vaanz May 31 '17 at 02:36
  • 1
    PowerMock disables EclEmma code coverage https://github.com/powermock/powermock/issues/422. And there is no workaround to have code coverage in IDE. But you can use JaCoCo Offline Instrumentation to get code coverage https://github.com/powermock/powermock/wiki/Code-coverage-with-JaCoCo#offline-instrumentation . Appreciate upvote/accept of answer :) – kism3t May 31 '17 at 05:05
  • Yes, we are using EclEmma code coverage. I will try using other code coverage libraries to check. Thank you so much. – Vaanz May 31 '17 at 10:41