如何为通知编写Android单元测试?

5
我有一个名为handleFirebaseMessages的类,其中包含函数onMessageReceived()。这个函数负责接收数据并创建通知。 onMessageReceived()函数接收RemoteMessages对象中的数据。我正在尝试为这个函数编写测试,但是我还没有完全搞清楚它。 HandleFirebaseMessages
public class HandleFirebaseMessages extends FirebaseMessagingService {
@Override
    public void onMessageReceived(final RemoteMessage remoteMessage) {
   final Map<String, String> data = remoteMessage.getData();
    //create notifications using NotificationCompat.Builder
    }
 }

我已经能够编写部分测试代码。如何完成其余部分?

@Test
public  void testHandleFirebaseMessages() throws  Exception {

    Map<String,String> data=new HashMap<String,String>();
    data.put("id","4422");
    data.put("type", "1");
    data.put("imageUrl" , "https://image.freepik.com/free-vector/android-boot-logo_634639.jpg");
    data.put("smallTitle" , "DoJMA v2");
    data.put("smallSubTitle", "Update now from Google Play Store");
    data.put("ticker" , "New update for DoJMA");
    data.put("contentInfo" , "");
    data.put("link" , "https://photo2.tinhte.vn/data/avatars/l/1885/1885712.jpg?1402763583");
    data.put("className" , "HomeActivity");
    data.put("page" , "2");
    data.put("bigTitle" , "DoJMA Android app version 2 released!");
    data.put("bigSubTitle" , "Hi folks! New DoJMA update is here! Major redesigning and improvements! This app was made by the Mobile App Club.They work really hard man...and get good products");
    data.put("bigSummaryText" , "Update now");


    RemoteMessage message = new RemoteMessage.Builder("1")
            .setMessageId("1")
            .setData(data)
            .build();
    (new HandleFirebaseMessages()).onMessageReceived(message);

    //WHat now?
}
2个回答

6
您可以通过包装Notifications API使其可测试来进行测试。首先,您需要一种将模拟依赖项传递给包装器构造函数的方法。您可以编写类似于以下内容的代码:
class NotificationBuilderProvider {

    //TODO: implement Provider<NotificationCompat.Builder> if you are using JSR-330 annotations

    private Context context;

    NotificationBuilderProvider(Context context) {
        this.context = context;
    }

    @Override
    public NotificationCompat.Builder get() {
        return new NotificationCompat.Builder(context);
    }

}

现在你可以编写这样的包装器:
class NotificationsWrapper {

    private final NotificationBuilderProvider notificationBuilderProvider;
    private final NotificationManager notificationManager;

    NotficiationsWrapper(NotificationBuilderProvider notificationBuilderProvider, NotificationManager notificationManager) {
        this.notificationBuilderProvider = notificationBuilderProvider;
        this.notificationManager = notificationManager;
    }

    public void postNotification(Map<String, String> data) {
        Notification notification = notificationBuilderProvider.get()
            .setContentTitle(data.get("Title"))
            //etc
            .build();
        notificationManager.notify(ID, notification);
    }
}

现在你可以为NotificationWrapper编写单元测试,这比测试重量级服务更容易测试。
//mocks
NotificationBuilderProvider mockNotificationBuilderProvider;
NotificationBuilder mockNotificationBuilder;
NotificationManager mockNotificationManager;


//system under test
NotificationWrapper notificationWrapper;

@Before
public void setUp() {
     mockNotificationBuilderProvider = Mockito.mock(NotificationBuilderProvider.class);
     mockNotificationBuilder = Mockito.mock(NotificationCompat.Builder.class, RETURNS_SELF);
     mockNotifyManager = Mockito.mock(NotificationManager.class);
}

@Test
public void givenTitleInData_whenPost_thenNotificationHasContentTitle() {
     //arrange
     Map<String, String> data = new HashMap<>();
     data.put("Title", "MyTitle");

     //act
     notificationsWrapper.postNotification(data);

     //assert
     verify(notificationBuilder).setContentTitle(eq("Title"));
}

如果这一切看起来有点复杂,最好从为简单的类编写单元测试开始,直到您熟悉单元测试和模拟的概念为止。然后您可以逐步测试更复杂的类。Mockito文档是学习模拟和单元测试的好地方。祝你好运!

1
只是一个观察。在 notificationManager.notify(ID, notification) 中提到的 ID 应该在 NotificationsWrapper 的构建参数中接收,或者是该类的静态属性。 - Joaquin Iurchuk
3
另外,我认为你忘记声明类似于 when(mockNotificationBuilderProvider.get()).thenReturn(mockNotificationBuilder) 的东西了。 - Joaquin Iurchuk

-3

现在在onMessageReceived(message)中,创建一个自定义通知。

尝试这个链接自定义通知

希望这可以帮到你。


这不是关于设计问题,而是关于单元测试。 - Marfin. F

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接