3

Androidアプリに通知を送信するためにGCM(Google Cloud Messaging)を使用しています。私のサーバーは提供されたGoogleを使用しており、ドキュメントgcm-server.jarに従っています。デバイスに問題なく通知を送信できます。

今、私はのプライベートメソッドから返されたResultソース)に基づいてビジネスロジックをユニットテストしようとしています。PushNotificationDaoGcmImplsendNotificationToServer

クラスでResultあるためにモックすることはできず、パブリックコンストラクターがないため、単純にインスタンス化しても機能しないことを私は知っています。内部クラスは外部からアクセスできないため、その方法でオブジェクトを作成することはできません。 finalnew Result()ResultBuilderpackage com.google.android.gcm.server;

sourceResult )から返されるものを作成する良い方法が見つかりません。Sender

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
}
4

2 に答える 2

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);
    }
于 2012-12-05T21:40:31.657 に答える
2

com.google.android.gcm.serverパッケージにMockResultクラスを作成して、ビルダーにアクセスすることもできます。

package com.google.android.gcm.server;

class MockResult {

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

}

私にとって、これはリフレクションを扱うよりも管理しやすいと感じます。

于 2012-12-31T02:27:14.183 に答える