Java 如何使用多个ArgumentCaptor参数

Java 如何使用多个ArgumentCaptor参数,java,unit-testing,junit,mockito,Java,Unit Testing,Junit,Mockito,当我使用超过1个ArgumentCaptor参数时,我会收到一个空指针。可能有人知道出了什么问题 @RunWith(PowerMockRunner.class) @PrepareForTest(FileHelper.class) public class MyTest { ... @Before public void setUp() throws Exception { PowerMockito.mockStatic(FileHelper.class); } @Test public

当我使用超过1个ArgumentCaptor参数时,我会收到一个空指针。可能有人知道出了什么问题

@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());

...
}
@RunWith(PowerMockRunner.class)
@PrepareForTest(FileHelper.class)
公共类MyTest{
...
@以前
public void setUp()引发异常{
mockStatic(FileHelper.class);
}
@试验
public void save()引发异常{
ArgumentCaptor argName=ArgumentCaptor.forClass(String.class);
ArgumentCaptor argList=ArgumentCaptor.forClass(List.class);
PowerMockito.doNothing().when(FileHelper.class,“saveTextFile”,argName.capture(),
argList.capture());
...
}
FileHelper类中的saveTextFile方法:

public static void saveTextFile(String filename, List<String> data) {
...
}
publicstaticvoidsavetextfile(字符串文件名,列表数据){
...
}
如果我运行代码,会出现以下异常:

java.lang.NullPointerException 位于java.lang.Class.isAssignableFrom(本机方法) 位于org.powermock.reflect.internal.WhiteboxImpl.checkifParameterTypesAreName(WhiteboxImpl.java:2432) 位于org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1934) 位于org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025) 位于org.powermock.reflect.internal.WhiteboxImpl.FindMethodorThroweException(WhiteboxImpl.java:948) 位于org.powermock.reflect.internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:882) 位于org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:859) 位于org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466) 位于org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:106)


如果我调用一个只有一个参数的方法,即list参数,则一切正常。

我认为您可能希望使用“verify”而不是when

您正在设置一个期望,希望在模拟上“什么也不做”

调用正在测试的方法,然后验证您期望发生的事情,不是更好吗

例如,考虑这两个类…

HelperClass.java

public class HelperClass {

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

public class MyClass {

    public void testMethod() {
        HelperClass.nastyStaticCall("FILENAME", Arrays.asList("Data"));
    }
}
如果我想测试“MyClass”,我会这样做

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");
    }
}
导入静态org.fest.assertions.assertions.assertThis;
导入静态org.powermock.api.mockito.PowerMockito.mockStatic;
导入静态org.powermock.api.mockito.PowerMockito.verifyStatic;
导入java.util.List;
导入org.junit.Before;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入org.mockito.ArgumentCaptor;
导入org.mockito.Captor;
导入org.mockito.MockitoAnnotations;
导入org.powermock.core.classloader.annotations.PrepareForTest;
导入org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(HelperClass.class)
公共类MyClassTest{
私有MyClass类未测试;
@俘虏
私有参数捕获器fileNameCaptor;
@俘虏
私有参数捕获器数据捕获器;
@以前
公共作废设置(){
initMocks(this);
mockStatic(HelperClass.class);
classUnderTest=新建MyClass();
}
@试验
public void应该makeNastyStaticCall(){
classUnderTest.testMethod();
verifyStatic();
HelperClass.nastyStaticCall(fileNameCaptor.capture(),dataCaptor.capture());
assertThat(fileNameCaptor.getValue()).isEqualTo(“文件名”);
资产(dataCaptor.getValue())。仅包含(“数据”);
}
}
如您所见,此测试方法所做的只是调用实际代码,然后验证是否使用正确的参数调用了helper类

如果您实际期望一个静态方法调用返回一个值,该值将由您正在测试的方法的其余部分使用,那么您需要使用“when”,但由于它返回“void”,您不需要做任何事情

一般来说,我个人避免在“when”子句中使用参数捕捉器,并将其留给“verify”阶段


希望这有帮助。

这似乎是一个问题。您没有指定方法是否重载,但因为堆栈跟踪一直到相同的行号,所以我将其标记为的副本。希望这个答案对您有所帮助!感谢您提供的信息。我重命名了该方法,它可以工作!