PowerMock参数捕获器为新的Intent返回null

时间:2018-10-17 20:21:21

标签: android powermockito

这是我的主要课程以及我要测试的方法

public class MyClass {

    public void startEmailActivity(FragmentActivity activity, @NotNull String emailUrl) {
        if (isMyEmailAppInstalled()) {
            Intent myEmailAppIntent = new Intent(Intent.ACTION_SENDTO, Uri.parse(emailUrl));
            myEmailAppIntent.setClassName(MY_PACKAGE_NAME, MY_EMAIL_COMPOSE_ACTIVITY_EMAIL);
            activity.startActivity(intent);
        } 
    }

这是测试类和方法。假设我已经在isMyEmailAppInstalled()方法中嘲笑了必要的调用,使其返回true

@RunWith(PowerMockRunner.class)
@PrepareForTest(Uri.class)
public class MyClassTest {
    @Mock
    FragmentActivity mockActivity;
    @Mock
    private Uri mockUri;
    @Captor
    private ArgumentCaptor<Intent> intentArgumentCaptor;

    private static final String MOCK_EMAIL_URL = "mailto:mock@mock.com";

    @Test
    public void testStartEmailActivity() throws Exception {

        doNothing().when(mockActivity).startActivity(any(Intent.class));
        mockStatic(Uri.class);
        when(Uri.parse(MOCK_EMAIL_URL)).thenReturn(mockUri);       

        MyClass testObject = new MyClass();
        testObject.startEmailActivity(mockActivity, MOCK_EMAIL_URL);

        intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mockActivity).startActivity(intentArgumentCaptor.capture());
        Intent sentIntent = intentArgumentCaptor.getValue();
        //sentIntent is null here :( Below lines of code throws NPE when test is run
        Assert.assertTrue(sentIntent.getComponent().getClassName().equalsIgnoreCase(MY_EMAIL_COMPOSE_ACTIVITY_EMAIL));
        Assert.assertTrue(sentIntent.getComponent().getPackageName().equalsIgnoreCase(MY_PACKAGE_NAME));
    }
}

任何人都知道为什么参数captor将返回null?看起来很简单,可能是我遗漏了一些东西。

1 个答案:

答案 0 :(得分:0)

啊哈!我发现了丢失的那一块。 基本上我需要两件事。

  1. 为被测类添加preparefortest,这将使powermock可以进入其中并帮助进行模拟,即

    @PrepareForTest({Uri.class,MyClass.class})

  2. 使用whenNew()模拟新对象的构造

    whenNew(Intent.class).withAnyArguments().thenReturn(mockIntent);
    

这就是我的最终测试方法的样子

@Test
public void testStartEmailActivity() throws Exception {

    doNothing().when(mockActivity).startActivity(any(Intent.class));
    mockStatic(Uri.class);
    when(Uri.parse(MOCK_EMAIL_URL)).thenReturn(mockUri);       
    when(mockIntent.setClassName(MY_PACKAGE_NAME, MY_EMAIL_COMPOSE_ACTIVITY_EMAIL)).thenReturn(mockIntent);
    whenNew(Intent.class).withAnyArguments().thenReturn(mockIntent);

    MyClass testObject = new MyClass();
    testObject.startEmailActivity(mockActivity, MOCK_EMAIL_URL);
    verify(mockActivity).startActivity(mockIntent);

}