简体   繁体   English

如何使用多个ArgumentCaptor参数

[英]How to use multiple ArgumentCaptor parameter

When I use more than 1 ArgumentCaptor parameter I receive a Nullpointer. 当我使用超过1个ArgumentCaptor参数时,我收到一个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: FileHelper类中的saveTextFile方法:

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) org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl)中org.powermock.reflect.internal.WhiteboxImpl.checkIfParameterTypesAreSame(WhiteboxImpl.java:2432)的java.lang.Class.isAssignableFrom(Native Method)中的java.lang.NullPointerException .java:1934)org.powermock.refree.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025)atg.powermock.refree.internal.WhiteboxImpl.findMethodOrThrowException(WhiteboxImpl.java:948)org.powermock.reflect。 org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:859)的org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:466)中的internal.WhiteboxImpl.doInvokeMethod(WhiteboxImpl.java:882) .powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:106)

If I call a method that has only one argument, ie the list argument everything works fine. 如果我调用一个只有一个参数的方法,即list参数一切正常。

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 HelperClass.java

public class HelperClass {

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

MyClass.java 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... 如果我想测试“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");
    }
}

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. 如果您实际上期望静态方法调用返回一个值,该值将由您正在测试的方法的其余部分使用,那么您将需要使用“when”,但是当返回“void”时,您不需要做任何事。

In general, personally I avoid using argument captors in "when" clauses and leave these for the "verify" stages. 一般来说,我个人避免在“when”条款中使用参数捕获者,并将其留在“验证”阶段。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM