Захват аргумента PowerMock возвращает ноль для нового намерения - PullRequest
0 голосов
/ 17 октября 2018

Вот мой основной класс и метод, который я пытаюсь проверить

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 голосов
/ 18 октября 2018

Aha!Я обнаружил недостающую часть.По сути, мне нужно было две вещи.

  1. добавить подготовительный тест для тестируемого класса, который позволит 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);

}
...