How to write the unit test when using GeoCoordinates class with/without initializing the Navigate Engine
Summary
This article explains how to write unit tests for the HERE SDK GeoCoordinates class without initializing the Navigate Engine. Since GeoCoordinates is implemented as a final class, it cannot be mocked directly using the default Mockito configuration. This article describes two recommended approaches: enabling Mockito Inline Mock Maker or using a wrapper class around GeoCoordinates. These approaches allow developers to write and execute unit tests successfully without requiring Navigate Engine initialization.
Problem / Symptoms
When writing local unit tests for applications using the HERE SDK, developers may encounter one or more of the following issues:
Unit tests fail while testing code that uses the GeoCoordinates class.
Mockito cannot mock the GeoCoordinates class because it is a final class.
Navigate Engine is not initialized in the local unit test environment.
Runtime exceptions occur while creating or accessing GeoCoordinates.
Test execution fails because the SDK runtime is unavailable.
Cause
The HERE SDK GeoCoordinates class is implemented as a final class. By default, Mockito does not support mocking final classes. Additionally, local unit tests do not initialize the HERE Navigate Engine, preventing SDK runtime-dependent classes from being tested directly.
Solution
Use one of the following recommended approaches.
Option 1: Enable Mockito Inline Mock Maker (Since Mockito 2.1.0)
Enable Mockito Inline Mock Maker to support mocking final classes.
Create the following file:
Create a text file named org.mockito.plugins.MockMaker in your project's src/test/resources/mockito-extensions directory.
Add a single line to this file: mock-maker-inline.
Mockito can now mock final classes during unit testing.
Option 2: Create a Wrapper Class
Another approach is to create a non-final wrapper class around GeoCoordinates and then mock that wrapper class.
Here's an example of how to implement and test a wrapper class:
public class GeoCoordinatesWrapper {<br /><br />private final GeoCoordinates geoCoordinates;<br /><br />public GeoCoordinatesWrapper(double latitude, double longitude) {<br /><br />this.geoCoordinates = new GeoCoordinates(latitude, longitude);<br /><br />}<br /><br />public double getLatitude() {<br /><br />return geoCoordinates.getLatitude();<br /><br />}<br /><br />public double getLongitude() {<br /><br />return geoCoordinates.getLongitude();<br /><br />}<br /><br />}
Then create the unit test using Mockito to mock the wrapper class and verify the expected latitude and longitude values.
// In our test class
import org.mockito.Mockito;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class GeoCoordinatesWrapperTest {<br /><br />@Test<br /><br />public void testGeoCoordinatesWrapper() {<br /><br />// Create a mock of GeoCoordinatesWrapper<br /><br />GeoCoordinatesWrapper mockGeoCoordinatesWrapper = Mockito.mock(GeoCoordinatesWrapper.class);<br /><br />// Define behavior for the mock to return specific latitude and longitude<br /><br />Mockito.when(mockGeoCoordinatesWrapper.getLatitude()).thenReturn(52.53086);<br /><br />Mockito.when(mockGeoCoordinatesWrapper.getLongitude()).thenReturn(13.38469);<br /><br />// Use the mock in our test<br /><br />double latitude = mockGeoCoordinatesWrapper.getLatitude();<br /><br />double longitude = mockGeoCoordinatesWrapper.getLongitude();<br /><br />// Assert that the returned values are as expected<br /><br />assertEquals(52.53086, latitude, 0.00001);<br /><br />assertEquals(13.38469, longitude, 0.00001);<br /><br />}<br /><br />}
Procedure
Configure Mockito Inline Mock Maker or create a wrapper class.
Implement the required unit test.
Mock the wrapper class instead of the GeoCoordinates object when applicable.
Execute the unit tests.
Verify that all test assertions pass successfully.
Expected Result
After applying either solution:
Unit tests execute successfully.
Navigate Engine initialization is not required.
GeoCoordinates objects can be tested successfully.
Latitude and longitude values are returned correctly.
All unit test assertions pass successfully.
In this approach, we're testing with a wrapper class that delegates calls to the actual GeoCoordinates object. This allows us to mock the behavior of the wrapper class in our tests.
Additional Information
Customers can integrate the above in this example from GitHub - https://github.com/heremaps/here-sdk-examples/tree/master/examples/latest/navigate/android/Java/UnitTesting
Updated 3 days ago