Skip to content

Testing

Because contracts are runtime values, testing needs no Proxy tricks and no native toolchain. Both sides fake cleanly.

mockBridge produces a fully-typed mock from a contract — you implement only the members the test touches.

import { mockBridge } from '@malopezr7/bridgekit/test';
const mock = mockBridge(AppHost, {
isLoggedIn: async () => true,
});

createTestBridge() gives you an isolated registry wired to an in-memory loopback transport — JS provides and JS consumes, with no native side. Feature logic, including streams and state, runs in plain Jest.

import { createTestBridge } from '@malopezr7/bridgekit/test';
const { bridgekit } = createTestBridge();
bridgekit.provide(AppHost, { isLoggedIn: async () => true });
const app = bridgekit.bridge(AppHost);
expect(await app.isLoggedIn()).toBe(true);

Generated provider/client interfaces are plain Kotlin interfaces — fake them directly, no mocking framework required.

val fake = object : AppHost {
override suspend fun isLoggedIn(): Boolean = true
override suspend fun saveFile(params: SaveFileParams) = SaveFileResult.SUCCESS
override fun showLogin() {}
override fun notifications(): Flow<String> = flowOf("123456")
override val connectivity = MutableStateFlow(Connectivity(online = true))
}

Drive the unit under test directly against that fake. BridgeKit’s own constructor is internal, so there is no public way to build an isolated instance for a test — the shared BridgeKit.default is the only instance a consumer app can reach. Test your provider logic against the interface, not through the runtime.

The generated Swift provider is a plain protocol (AnyObject-bound, nothing BridgeKit-specific in the signatures). Conform a test double to it and inject that — no runtime, no Nitro, no simulator needed for the provider’s own logic.

final class FakeAppHost: AppHost {
func isLoggedIn() throws -> Bool { true }
func saveFile(_ params: SaveFileParams) async throws -> String { "success" }
func closeFeature() {}
func showWebpage(_ params: ShowWebpageParams) {}
// ...implement only the members the test exercises
}
// Drive the unit under test directly against the fake.
let host: any AppHost = FakeAppHost()
XCTAssertTrue(try host.isLoggedIn())

The JS consumer of that same contract is still tested in plain Jest with the loopback transport (createTestBridge / mockBridge above) — so both ends are covered without a device in the loop.

You don’t need to test that the two sides agree on the wire format. The single source of truth (one contract) plus the contract hash guarantee it — drift surfaces as a build failure (--check) or a structured runtime warning, not as a class of tests you maintain by hand. Codec round-trip tests can be generated alongside the Kotlin.