In this lesson, you will learn how to write integration tests that verify whether your JavaScript logic and Native code are communicating correctly across the bridge.
Why Test the Bridge?
When you build custom Native Modules or TurboModules, you are essentially creating a contract between the JavaScript runtime and the underlying platform (iOS or Android). A common source of bugs occurs when the data sent from JS doesn't match the expected types or structure on the native side—or when the asynchronous callback never returns.
Testing the architecture isn't about testing your UI buttons; it’s about testing the "handshake" between the two worlds.
Mocking the Native Interface
To test this, we treat the Native Module as an dependency that we can inject or mock. Instead of running the full native binary, we use tools like jest to create a "spy" on the Native Module to see if the bridge successfully receives the intended messages.
Consider a simple Native Module method DeviceLogger.log(message: string). You want to ensure that calling this function from JS correctly triggers the native implementation.
// The Integration Test
import DeviceLogger from './NativeDeviceLogger';
jest.mock('./NativeDeviceLogger', () => ({
log: jest.fn(),
}));
test('it should pass the log message to the native layer', () => {
const testMessage = "Hello Bridge";
DeviceLogger.log(testMessage);
// Verify communication integrity
expect(DeviceLogger.log).toHaveBeenCalledWith(testMessage);
});
Verifying Communication Integrity
For more complex scenarios, such as verifying data serialization, you should write an end-to-end integration test. By setting up a test suite that runs on the actual simulator, you can verify that data structures (like maps or arrays) are not losing information when crossing the bridge.
If your native side is written in C++ (via TurboModules), use the CodeGen output to ensure that the generated types match your JavaScript interface. If the types don't align, the build will fail, preventing bridge corruption before the app even starts.
Key Takeaway: Testing the architecture involves verifying that the "contract" between JavaScript and Native remains unbroken by mocking calls or running integration suites that specifically validate the data crossing the bridge.