Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Verify call to static method

I want to verify that a public static void method has been called.

@RunWith(PowerMockRunner.class)
@PrepareForTest({ConsoleLog.class})
public class AdContentDataUnitTest {

    @Before
    public void setUp() throws Exception {
        PowerMockito.mockStatic(ConsoleLog.class);
    }

    @Test
    public void adContentData_sendTrackingEvent_noUrl() throws Exception {
        mAdContentData = spy(mAdContentData);

        // PowerMockito.doNothing().when(ConsoleLog.class);

        verifyStatic();
        mAdContentData.sendTrackingEvent("event1");
        //verifyStatic();
    }
}

sendTrackingEvent will be invoked, and the ConsoleLog.v(String, String) will be called. I can see in debug that the static method is called, but the following log appear and the test fail:

Wanted but not invoked com.example.logger.ConsoleLog.v(
    "AdContentData",
    "sendTrackingEvent: event event1 does not exist."
);

I've tried to add the verifyStatic after but same log, and if I remove the first verify, nothing is checked. If I mock the whole ConsoleLog class the error Unfinished stubbing detected here: [...] PowerMockitoCore.doAnswer appear.

Does anyone know how to do it properly?

like image 218
Hugo Gresse Avatar asked Oct 19 '22 09:10

Hugo Gresse


1 Answers

Do anyone know how to do it properly?

Yes. Don't do it at all.

Let's say you have a class that calls a static method like this:

class Person {
    private final int id;

    Person() {
        id = IdGenerator.gen();
    }
}

Extract the static call to a non-static method:

class Person {
    private final int id;

    Person() {
        id = generateId();
    }

    protected int generateId() {
        return IdGenerator.gen();
    }
}

Now you can write a test, overriding the extracted method:

    final int id = 1;
    Person person = new Person() {
        @Override
        protected int generateId() {
            return id;
        }
    };

    // test with person, knowing we control id

But the ideal solution is actually to refactor the code under test to not use such static calls at all, but dependency injection.

like image 102
janos Avatar answered Oct 21 '22 05:10

janos