補足情報
単体テスト、スレッドセーフ、依存関係の管理など、重要な補足情報を以下に示します。
単体テスト
リリース パッケージの中には、静的メソッドを持つクラスでもモック化を有効にする heresdk-mock JAR ファイルが含まれています。コードにHERE SDKへの依存関係が含まれている場合、このライブラリは単体テストを記述するために必要になります。HERE SDKを初期化することなく単体テストを記述できます。
HERE SDKモックライブラリには、機能がなく中身のないスタブが含まれています。つまり、機能をシミュレートするためにモッキングを使用する必要があります。たとえば、GeoCoordinates コンストラクタにコードが含まれていないため、渡す値を設定できません。このため、geoCoordinates.latitudeの値はデフォルト値の 0 のままになります。
以下に、単体テストのビルド時にモック ライブラリを自動的に使用し、さらにアプリ コードのビルド時に実際の HERE SDK AAR を使用する Android Studio プロジェクトの手順を示します。
heresdk-mock-version-xxx.jar を heresdk-version-xxx.aar と同じ app/libs フォルダーに配置します。
アプリの build.gradle 設定に次の依存関係を使用します。
def getHereSdkArtefactName() {
def aarFile = fileTree(dir: 'libs', include: ['heresdk-*.aar']).first()
// Filename without extension is necessary.
return org.apache.commons.io.FilenameUtils.getBaseName(aarFile.name)
}
// Exclude HERE SDK's AAR from unit test's dependencies.
configurations.testImplementation {
exclude module: getHereSdkArtefactName()
}
dependencies {
implementation(name: getHereSdkArtefactName(), ext:'aar')
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation fileTree(dir: 'libs', include: ['*mock*.jar'])
testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:3.1.0'
}この設定により、アプリで単体テストを実行するときはモック JAR を使用し、アプリをビルドするときは実際の HERE SDK AAR を使用します。
以下に、Mockito を使用した例を示します。これは、モック化されたオブジェクトを作成できる他のほとんどのフレームワークとも連携します。
@RunWith(MockitoJUnitRunner.class)
public class TestExample {
@Test
public void testNonStaticMethod() {
Angle angleMock = mock(Angle.class);
when(angleMock.getDegrees()).thenReturn(10.0);
assertEquals(10.0, angleMock.getDegrees());
verify(angleMock, times(1)).getDegrees();
verifyNoMoreInteractions(angleMock);
}
@Test
public void testStaticMethod() {
Angle angleMock = mock(Angle.class);
when(angleMock.getDegrees()).thenReturn(10.0);
// Each HERE SDK class with static methods contains helper code to make mocking easier.
// Add heresdk-xxx.jar to access these additional mock helper instances.
Angle.StaticMockHelperInstance = mock(Angle.StaticMockHelper.class);
when(Angle.StaticMockHelperInstance.fromRadians(anyDouble())).thenReturn(angleMock);
// Test static creation of Angle class. Static HERE SDK classes require a StaticMockHelperInstance.
assertEquals(10.0, Angle.fromRadians(0.174533).getDegrees());
verify(Angle.StaticMockHelperInstance, times(1)).fromRadians(anyDouble());
verify(angleMock, times(1)).getDegrees();
verifyNoMoreInteractions(Angle.StaticMockHelperInstance);
verifyNoMoreInteractions(angleMock);
}
...
}「UnitTesting」サンプル アプリで、その他のユースケースの例を確認してください。
コンストラクタ ヘルパーを使用する
モック ライブラリにはコンストラクタ ヘルパーがあり、構造体のようなクラスの初期化を助けます。これらのヘルパーは、コンストラクタのパラメーター名と名前が一致する 静的でないパブリック フィールドを自動的に初期化します。パラメーター名とフィールド名が一致しない場合は、カスタム実装を提供できます。
カスタム実装を提供するには、ConstructorHelper インターフェースを実装するか ConstructorHelperImpl クラスを拡張して、この実装に ConstructorMockHelperInstance フィールドを設定します。
ConstructorHelper インターフェースには _constructor(...) という名前のメソッドが含まれ、ネストされているクラス内のコンストラクタごとに 1 つのメソッドがあります。それぞれの _constructor(...) メソッドは関連するコンストラクタと同じパラメーターを持ち、クラスのインスタンスを返します。
ConstructorHelperImpl クラスは ConstructorHelper インターフェースを実装し、前述のようにデフォルトの実装を提供します。このクラスを拡張して、選択した _constructor(...) メソッドのみを上書きできます。パラメーターのないコンストラクタを除く各コンストラクタは、対応するバージョンの ConstructorMockHelperInstance._constructor(...) を呼び出し、返されたインスタンスのすべてのパブリック フィールドを現在のインスタンスにコピーします。
コンストラクタにメンバーとして公開されていないパラメーター名が含まれている場合は、ConstructorMockHelperInstanceアプローチを使用します。この例は次のとおりです。
class GeoCoordinatesUpdateMockHelper extends GeoCoordinatesUpdate.ConstructorHelperImpl {
/**
* The default implementation of `GeoCoordinatesUpdate.ConstructorHelperImpl` can't initializie the `latitude`,
* `longitude`, and `altitute` fields of the `GeoCoordinatesUpdate` class. To initialize those fields,
* you must use custom logic.
*/
public GeoCoordinatesUpdate _constructor(@NonNull final GeoCoordinates coordinates) {
// Each class of the HERE SDK Mock Library contains a parameterless constructor even if the original class doesn't.
// This constructor can be used to create instances of the class and initialize
// fields with default values.
GeoCoordinatesUpdate _result = new GeoCoordinatesUpdate();
_result.latitude = coordinates.latitude;
_result.longitude = coordinates.longitude;
_result.altitude = coordinates.altitude;
// All public fields are copied in constructor
// "GeoCoordinatesUpdate(@NonNull final GeoCoordinates coordinates)"
return _result;
}
}カスタム コンストラクタを使用した単体テスト
@RunWith(MockitoJUnitRunner.class)
public class TestBasicTypes {
@Before
public void SetUp() {
// Use custom logic for constructors of "GeoCoordinatesUpdate" class.
GeoCoordinatesUpdate.ConstructorMockHelperInstance = new GeoCoordinatesUpdateMockHelper();
}
@After
public void TearDown() {
// Reset to the default implementation.
GeoCoordinatesUpdate.ConstructorMockHelperInstance = new GeoCoordinatesUpdate.ConstructorHelperImpl();
}
@Test
public void testAutoGeneratedConstructor() {
// "GeoCoordinates" has constructor with parameters "latitude" and "longitude" and
// fields with the same names. In the example, the fields are
// initalized by the constructor's parameters and "altitude" has the default value.
GeoCoordinates geoCoordinates = new GeoCoordinates(10.0, 20.0);
assertEquals(geoCoordinates.latitude, 10.0);
assertEquals(geoCoordinates.longitude, 20.0);
}
@Test
public void testSelfImplementedConstructor() {
GeoCoordinates geoCoordinates = new GeoCoordinates(5.0, 10.0, 20.0);
// This constructor uses "GeoCoordinatesUpdateMockHelper" which is set in "SetUp".
GeoCoordinatesUpdate geoCoordinatesUpdate = new GeoCoordinatesUpdate(geoCoordinates);
assertEquals(geoCoordinatesUpdate.latitude, 5.0);
assertEquals(geoCoordinatesUpdate.longitude, 10.0);
assertEquals(geoCoordinatesUpdate.altitude, 20.0);
}
}HERE SDKの使用状況統計情報を追跡する
HERE SDKは、UsageStatsを使用してネットワークの使用状況を監視する方法を提供します。このクラスは、アップロードおよびダウンロードされたデータに関する統計情報を収集します。sdkNativeEngine.getSdkUsageStats()とsdkNativeEngine.enableUsageStats()を使用してネットワークの統計情報を取得します。カウンターをリセットするには、sdkNativeEngine.clearPersistentUsageStats()とsdkNativeEngine.clearUsageStatsCache()を使用します。トラッキングを有効化するには、次を使用します。
SDKNativeEngine.getSharedInstance().enableUsageStats(true);有効化すると、HERE SDKは異なるモジュール間でネットワーク使用状況を追跡します。追跡したデータを取得して記録するには、次のメソッドを使用します。
private void logUsageStats() {
List<UsageStats> currentUsageStats = SDKNativeEngine.getSharedInstance().getSdkUsageStats();
for (UsageStats usageStat : currentUsageStats) {
Log.d("UsageStats", "Network usage for feature: " + usageStat.feature.name());
for (UsageStats.NetworkStats currentNetworkUsage : usageStat.networkStats) {
Log.d("UsageStats", "Bytes sent: " + currentNetworkUsage.sentBytes);
Log.d("UsageStats", "Bytes received: " + currentNetworkUsage.receivedBytes);
Log.d("UsageStats", "Network requests sent: " + currentNetworkUsage.requestCounter);
Log.d("UsageStats", "For method: " + currentNetworkUsage.methodCall);
}
}
}ログの例は次のようになります。ログには、対応するマップデータレイヤーのデータがアプリケーションによってリクエストされたときに発生するRENDERINGレイヤーがカウントされたことが示されています。
Network Usage for feature: RENDERING
Bytes sent: 12843
Bytes received: 257590
Network requests sent: 10
For method MapContent%RENDERINGUsageStatsには、RENDERINGやSEARCHなどの各Featureに対応するNetworkStatsのリストが含まれます。各NetworkStatsエントリーには、sentBytes、receivedBytes、requestCounter、およびそれぞれのFeatureで対応するmethodCallが含まれます。UsageStatsは、現在のアプリセッションでのみ保持されます。
他の設定と同様に、enableUsageStats() の呼び出しは HERE SDK によって保持されません。そのため、UsageStats が実行時以前に有効になっており、ネットワーク統計の追跡を継続する場合は、HERE SDK を初期化する前に毎回これを有効にします。また、収集されたデータは、デバイス上で実行されたアプリの HERE SDK の使用量のみを集計していることに注意してください。
スレッド セーフ
HERE SDK では、スレッド セーフであることは保証されていません。メイン スレッドから SDK を呼び出す必要があります。内部的には、HERE SDK はほとんどの作業をバックグラウンド スレッドにオフロードしますが、コードへのコールバックは常にメイン スレッドで行われます。一般的に、スレッド セーフの確保は呼び出し元の責任です。たとえば、コードが同期されていない限り、さまざまなスレッドで 1 つのエンジンを再利用することは安全ではありません。
依存関係の管理
現時点では、Gradle などを使用する依存関係管理はまだサポートされていません。つまり、HERE SDK AARバイナリは、「HERE SDKを統合する」トピックで説明されているように、アプリケーションプロジェクトにローカルでコピーする必要があります。
HERE SDK を他のフレームワークと使用する
HERE SDK は他のフレームワークと併用できます。たとえば、希望する場合はオープン ストリート マップと SearchEngine を結合できます。
-
Xamarin:HERE SDK は Xamarin をサポートしていませんが、HERE SDK が提供する公開 API に Xamarin のラッパーを実装できます。HERE SDK に変更を加えて Xamarin 向けの関連するテスト ツールをサポートするお約束はできません。
-
React Native:React Native はサポートされていません。ただし、お客様ご自身でラッパーを実装することはできます。しかし、このようなタスクに対するサポートは提供していません。
7 日前の更新










