Модульный тест не пройден, когда BroadcastReceiver отправляет Intent IntentService - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть BroadcastReceiver, который запускает IntentService:

@Override
public void onReceive(Context context, Intent intent) {

    ParamsRequest paramsRequest = new ParamsRequest.Builder()
            .setUrl(intent.getStringExtra("url"))
            .build();

    Intent serviceIntent = new Intent(context, MyIntentService.class);
    serviceIntent.putExtra("paramsKey", paramsRequest);
    context.startService(serviceIntent);
}

И MyIntentService получает Intent (с объектом paramsRequest):

@Override
protected void onHandleIntent(Intent intent) {

    ParamsRequest paramsRequest = (ParamsRequest) intent.getSerializableExtra("paramsKey");

    //more code
}

У меня есть тест, чтобы убедиться, что намерение отправлено и получено правильно:

@Test
public void testStartAndroidProofService() {
    Intent intent = new Intent(context, AndroidProofService.class);
    intent.putExtra("paramsKey", paramsRequest);

    receiver.onReceive(context, intent);
    assertNull(receiver.getResultData());

    ArgumentCaptor<Intent> argumentIntent = ArgumentCaptor.forClass(Intent.class);
    Mockito.verify(context, times(1)).startService(argumentIntent.capture());
    assertEquals(paramsRequest, argumentIntent.getValue().getSerializableExtra("paramsKey"));
}

Но AssertEquals не удается:

enter image description here

Есть идеи, почему у меня 2 разных объекта?

РЕДАКТИРОВАТЬ: Intent, захваченный в argumentIntent.capture(), содержит объект ParamsRequest, но все поля в этомобъект null.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Хорошо, я наконец узнал, что происходит.Корень проблемы состоял в том, что поток, который я думал о процессе, был неправильным:

  1. Создайте Intent и установите ParamsRequest в качестве дополнительного
  2. Передайте этоIntent до BroadcastReceiver - onReceive()
  3. onReceive() выполняет операции с данными в Intent
  4. Вызов startService() с указанным выше Intent

Проблемы, обнаруженные в приведенной выше логике:

  • Я устанавливаю ParamsRequest объект в качестве дополнительного в Intent, полученном в onReceive().Это неправильно, потому что ParamsRequest объект должен быть построен внутри onReceive().

  • Я сравниваю Intent, полученный в onReceive(Context, Intent)с Intent, отправленным в startService(Intent), как если бы они были одинаковыми Intent.Это неправильно, потому что они отличаются Intents, так как второй Intent, который используется в startService(Intent), построен из данных, содержащихся в первом Intent.

Итак, фиксированный тест:

@Test
public void testStartService() {
    // I build the Intent that the onReceive() will receive
    Intent intent = new Intent();
    intent.putExtra("url", "https://fakeurl.com");

    //I simulate that the BroadcastReceiver is triggered, calling the onReceive() method and passing the above Intent
    receiver.onReceive(context, intent);

    //The actual code inside onReceive() instantiates a new Intent and calls startService(Intent)

    // I capture the new Intent instantiated inside the onReceive() method
    ArgumentCaptor<Intent> argumentIntent = ArgumentCaptor.forClass(Intent.class);
    Mockito.verify(context, times(1)).startService(argumentIntent.capture());

    //I retrieve the url from the ParamsRequest object setted in the captured Intent        
    ParamsRequest paramsRequest = (ParamsRequest) argumentIntent.getValue().getSerializableExtra("paramsRequest_key");
    String url = paramsRequest.getUrl();
    assertEquals("https://fakeurl.com", url);
}

И тест успешно пройден.

0 голосов
/ 27 ноября 2018

Речь идет о сериализации.

Когда вы помещаете ParamsRequest в Intent, под капотом, все поля в ParamsRequest преобразуются в string, boolean, int и т. Д., Чтобы их можно было сохранить,Позже, когда вы извлекаете ParamsRequest из Intent, все эти значения собираются и создается новый ParamsRequest.Следовательно, начальные ParamsRequest и вторые ParamsRequest являются разными объектами, и затем вы получаете ошибку утверждения.

Здесь вы хотите сравнить каждое поле или ParamsRequest или переопределить equalsParamsRequest.

...