Android中FCM推送通知测试:如何Mock RemoteMessage执行JUnit测试
Absolutely! Mocking RemoteMessage for JUnit tests is totally doable, and there are a few straightforward approaches depending on how much control you need over the mock object. Here are my go-to methods:
1. Directly Construct a RemoteMessage Object
The RemoteMessage class has public constructors (compatibility varies slightly by FCM version) that let you build a real instance with mock data or notifications. This is great if you need a fully functional object for testing.
// Create a RemoteMessage with custom data Map<String, String> mockData = new HashMap<>(); mockData.put("order_id", "12345"); mockData.put("status", "shipped"); RemoteMessage mockMessage = new RemoteMessage(mockData); // Add a mock notification (adjust based on your FCM version) RemoteMessage.Notification mockNotification = new RemoteMessage.Notification.Builder() .setTitle("Order Update") .setBody("Your order has been shipped!") .setIcon("ic_notification") .build(); // Bundle the notification and create a new message Bundle messageBundle = new Bundle(); messageBundle.putParcelable(RemoteMessage.EXTRA_NOTIFICATION, mockNotification); messageBundle.putStringArray(RemoteMessage.EXTRA_DATA_KEYS, mockData.keySet().toArray(new String[0])); messageBundle.putStringArray(RemoteMessage.EXTRA_DATA_VALUES, mockData.values().toArray(new String[0])); RemoteMessage messageWithNotification = new RemoteMessage(messageBundle);
2. Mock with Mockito
If you don't need a real instance and just want to stub specific methods (like getData() or getNotification()), Mockito is your friend. This keeps tests focused on the logic you care about.
First, make sure you have Mockito in your test dependencies, then use it to create a mock and stub behaviors:
// Mock the RemoteMessage itself RemoteMessage mockRemoteMessage = Mockito.mock(RemoteMessage.class); // Stub the getData() method to return your test data Map<String, String> testData = new HashMap<>(); testData.put("user_id", "67890"); Mockito.when(mockRemoteMessage.getData()).thenReturn(testData); // Stub the notification-related methods RemoteMessage.Notification mockNotification = Mockito.mock(RemoteMessage.Notification.class); Mockito.when(mockNotification.getTitle()).thenReturn("Test Alert"); Mockito.when(mockNotification.getBody()).thenReturn("This is a test notification"); Mockito.when(mockRemoteMessage.getNotification()).thenReturn(mockNotification);
3. Create a Reusable Mock Builder
For larger test suites, a custom builder class can save you time by encapsulating the logic to create RemoteMessage instances with different configurations.
public class RemoteMessageMockBuilder { private final Map<String, String> data = new HashMap<>(); private RemoteMessage.Notification notification; public RemoteMessageMockBuilder addData(String key, String value) { data.put(key, value); return this; } public RemoteMessageMockBuilder setNotification(String title, String body) { this.notification = new RemoteMessage.Notification.Builder() .setTitle(title) .setBody(body) .build(); return this; } public RemoteMessage build() { Bundle bundle = new Bundle(); bundle.putStringArray(RemoteMessage.EXTRA_DATA_KEYS, data.keySet().toArray(new String[0])); bundle.putStringArray(RemoteMessage.EXTRA_DATA_VALUES, data.values().toArray(new String[0])); if (notification != null) { bundle.putParcelable(RemoteMessage.EXTRA_NOTIFICATION, notification); } return new RemoteMessage(bundle); } } // Usage in tests: RemoteMessage testMessage = new RemoteMessageMockBuilder() .addData("product_id", "abc123") .setNotification("New Product", "Check out our latest item!") .build();
Quick Notes to Keep in Mind
- FCM Version Compatibility: Some
RemoteMessageconstructors or internal APIs may change between FCM versions. If you hit access issues, check if the method is marked@VisibleForTesting(common in newer versions). - Test Dependencies: Ensure your
build.gradleincludes the FCM library for testing (e.g.,testImplementation 'com.google.firebase:firebase-messaging:x.x.x'). - Keep Tests Focused: Only mock or construct the parts of
RemoteMessageyour test actually uses—no need to overcomplicate it!
内容的提问来源于stack exchange,提问作者CoDe

