2012-12-03 67 views
3

我正在使用GCM(Google Cloud Messaging)將通知發送到Android應用程序。我的服務器使用Google提供的gcm-server.jar,我遵循documentation。我能夠發送通知沒有問題的設備。Java服務器端單元測試GCM的結果

現在我試圖基於從PushNotificationDaoGcmImpl的專用方法sendNotificationToServer返回的Resultsource)進行單元測試業務邏輯。

我知道Result不能被模擬,因爲它是一個final類,並且簡單地將它實例化爲new Result()將不起作用,因爲沒有公共構造函數。在package com.google.android.gcm.server;之外,Result內部Builder類是無法訪問的,所以我不能用這種方式構建對象。

我找不到創建Result的好方法,它是從Sendersource)返回的內容。

我的問題是我將如何去單元測試PushNotificationDaoGcmImpl處理某些條件的基礎上Result

public class PushNotificationDaoGcmImpl{ 

    //method I'm trying to test 
    public void sendPushNotification(){ 
     // builds message to send 

     Result result = this.sendNotificationToServer(gcmMessage, deviceToken) 

     //handle result's error conditions 
    } 

    //method call I'm trying to mock 
    private Result sendNotificationToServer(Message gcmMessage, String deviceToken){ 
     return gcmSender.send(gcmMessage, deviceToken, 1); 
    } 
} 

//test snipet 
@Test 
public void testSendNotificationToServer() throws Exception { 
    Result result = new Result(); 

    PushNotificationMessage message = new PushNotificationMessage("123", "Test", "deviceToken", "Android"); 

    //Having issue with how to handle Result here 
    doReturn(result).when(gcmPushNotificationDaoSpy).sendNotificationToServer(any(Message.class), anyString()); 

    PushNotificationResult result = gcmPushNotificationDaoSpy.sendPushNotification(message); 

    //verify business logic was correct based on Result 
} 

回答

2

您還可以在com.google.android.gcm.server包中創建一個MockResult類,以便您訪問Builder。

package com.google.android.gcm.server; 

class MockResult { 

    public static Result mockResult(...) { 
     // Use Builder here to construct Result 
    } 

} 

對我來說,這比處理反射感覺更容易管理。

2

我來的解決方案是使用反射來創建一個Result對象。我不確定這是否是一種很好的方法,但我可以根據不同的Result錯誤代碼測試業務邏輯。

@Test 
public void testSendNotificationToServer() throws Exception { 
    String successIndicator = null; 
    Result result = buildFauxResult("messageId", "deviceToken", successIndicator); 

    PushNotificationMessage message = new PushNotificationMessage("123", "Test", "deviceToken", "Android"); 

    //Having issue with how to handle Result here 
    doReturn(result).when(gcmPushNotificationDaoSpy).sendNotificationToServer(any(Message.class), anyString()); 

    PushNotificationResult result = gcmPushNotificationDaoSpy.sendPushNotification(message); 

    //verify business logic was correct based on Result 
} 

public Result buildFauxResult (String messageId, String canonicalRegistrationId, String errorCode) throws Exception { 
      Class <?> builderClass = Class.forName("com.google.android.gcm.server.Result$Builder"); 
      Constructor <?> builderConstructor = builderClass.getDeclaredConstructors()[0]; 
      ReflectionUtils.makeAccessible(builderConstructor); 
      Object builderObject = builderConstructor.newInstance(); 

      Method canonicalRegistrationIdMethod = builderClass.getMethod("canonicalRegistrationId", String.class); 
      ReflectionUtils.makeAccessible(canonicalRegistrationIdMethod); 
      builderObject = ReflectionUtils.invokeMethod(canonicalRegistrationIdMethod, builderObject, canonicalRegistrationId); 

      Method messageIdMethod = builderClass.getMethod("messageId", String.class); 
      ReflectionUtils.makeAccessible(messageIdMethod); 
      builderObject = ReflectionUtils.invokeMethod(messageIdMethod, builderObject, messageId); 

      Method errorCodeMethod = builderClass.getMethod("errorCode", String.class); 
      ReflectionUtils.makeAccessible(errorCodeMethod); 
      builderObject = ReflectionUtils.invokeMethod(errorCodeMethod, builderObject, errorCode); 

      Method buildMethod = builderClass.getMethod("build"); 
      ReflectionUtils.makeAccessible(buildMethod); 

      return (Result) ReflectionUtils.invokeMethod(buildMethod, builderObject); 
    }