5

When I use more than 1 ArgumentCaptor parameter I receive a Nullpointer. May be anyone has an idea what goes wrong?

@RunWith(PowerMockRunner.class)
@PrepareForTest(FileHelper.class)
public class MyTest {

...

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


@Test
public void save() throws Exception {
ArgumentCaptor<String> argName = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<List> argList = ArgumentCaptor.forClass(List.class);
PowerMockito.doNothing().when(FileHelper.class, "saveTextFile", argName.capture(),
    argList.capture());

...
}

The saveTextFile methods in the FileHelper class:

public static void saveTextFile(String filename, List<String> data) {
...
}

If I run the code I get this exception:

java.lang.NullPointerException at java.lang.Class.isAssignableFrom(Native Method) at org.powermock.reflect.internal.WhiteboxImpl.checkIfParameterTypesAreSame(WhiteboxImpl.java:2432) at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1934) at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025) at org.powermock.reflect.internal.WhiteboxImpl.findMethodOrThrowException(WhiteboxImpl.java:948) at org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:882) at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:859) at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466) at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:106)

If I call a method that has only one argument, i.e. the list argument everything works fine.

2
  • This seems to be a common problem. You didn't specify whether your method is overloaded, but because the stack trace is the same down to the same line numbers, I'm marking it as a duplicate of this other question. Hope that answer helps you! Commented Jun 7, 2014 at 19:18
  • Thanks for the information. I renamed the method and it works! Commented Jun 9, 2014 at 9:41

1 Answer 1

2

I think you probably want to use "verify" instead of when.

You are setting an expectation to "do nothing" on your mock.

Wouldn't it be better to call the method being tested and then verify what you expected to happen did happen?

For example, consider these two classes...

HelperClass.java

public class HelperClass {

    public static void nastyStaticCall(String filename, List<String> data) {
       System.out.println("REAL METHOD CALLED!!");
    }
}

MyClass.java

import java.util.Arrays;

public class MyClass {

    public void testMethod() {
        HelperClass.nastyStaticCall("FILENAME", Arrays.asList("Data"));
    }
}

If I wanted to test "MyClass", I'd do something like this...

import static org.fest.assertions.Assertions.assertThat;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;

import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(HelperClass.class)
public class MyClassTest {

    private MyClass classUnderTest;

    @Captor
    private ArgumentCaptor<String> fileNameCaptor;

    @Captor
    private ArgumentCaptor<List<String>> dataCaptor;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        mockStatic(HelperClass.class);
        classUnderTest = new MyClass();
    }

    @Test
    public void shouldMakeNastyStaticCall() {
        classUnderTest.testMethod();

        verifyStatic();
        HelperClass.nastyStaticCall(fileNameCaptor.capture(), dataCaptor.capture());

        assertThat(fileNameCaptor.getValue()).isEqualTo("FILENAME");
        assertThat(dataCaptor.getValue()).containsOnly("Data");
    }
}

As you can see, all this test method does is call the actual code and then verify that the helper class was called with the correct arguments.

If you actually expected a static method call to return a value that would be used by the rest of the method you are testing, then you would need to use a "when", but as this returns "void", you don;t need to do anything.

In general, personally I avoid using argument captors in "when" clauses and leave these for the "verify" stages.

Hope this helps.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.