Skip to content
IC Reactor

installFakeReplica

installFakeReplica(options?): FakeReplica

Defined in: core/src/testing/fake-replica.ts:466

Stubs globalThis.fetch with a fake replica that runs options.canisters, so a Reactor, a DisplayReactor and the hooks built on them run end to end in a test, with no replica and nothing mocked in the agent.

Install it before the agents under test are built: an HttpAgent keeps the fetch it found when it was built. A ClientManager built at module scope is built when its module is first imported, so install the fake in a setup file, or import that module after installing it.

Point the agents at replica.host. By default it is where a ClientManager built with no host sends its calls: the page’s origin in a browser-like test environment such as jsdom, else http://127.0.0.1:4943. The fake answers the IC API there and refuses the IC API on any other origin as a network error, which it also logs once, so a test never reaches a real network by mistake. Every other request, on any origin, goes to the fetch it replaced. A fake installed while another is installed answers its own host and hands the IC API on any other origin to the earlier one.

It checks each request’s signatures as a replica does, and refuses one that does not verify with HTTP 400. It can check Ed25519, ECDSA P-256 and secp256k1 keys, including delegation chains between them, which covers Ed25519KeyIdentity, ECDSAKeyIdentity, Secp256k1KeyIdentity and a DelegationIdentity built from them. It refuses any other kind of key.

The signing uses @noble/curves, an optional peer dependency of @ic-reactor/core that @icp-sdk/core already installs. Add it to your devDependencies if your package manager does not let this package resolve it.

FakeReplicaOptions = {}

The canisters to run and the origin to answer for.

FakeReplica

The installed replica, with the requests it received and a restore() that puts the previous fetch back.

import { afterEach, beforeEach, expect, it } from "vitest"
import { QueryClient } from "@tanstack/query-core"
import { ClientManager, Reactor } from "@ic-reactor/core"
import {
createTestCanister,
installFakeReplica,
type FakeReplica,
} from "@ic-reactor/core/testing"
import { idlFactory, type _SERVICE } from "./declarations/backend"
const BACKEND = "bkyz2-fmaaa-aaaaa-qaaaq-cai"
let replica: FakeReplica
beforeEach(() => {
replica = installFakeReplica({
canisters: {
[BACKEND]: createTestCanister<_SERVICE>(idlFactory, {
greet: ([name]) => `Hello, ${name}!`,
}),
},
})
})
afterEach(() => replica.restore())
it("greets", async () => {
const backend = new Reactor<_SERVICE>({
clientManager: new ClientManager({
queryClient: new QueryClient(),
agentOptions: { host: replica.host },
}),
name: "backend",
canisterId: BACKEND,
idlFactory,
})
await expect(
backend.fetchQuery({ functionName: "greet", args: ["Ada"] })
).resolves.toBe("Hello, Ada!")
})