๐ธ Web Standards
- Web Standards Reference
- Encoding Reference
- Fetch Reference
- Request Reference
- Response Reference
- Streams Reference
- Using Streams
- Web Crypto Reference
Mocking Outbound fetch Requests
When using the API, Miniflare allows you to substitute custom Responses for
fetch() calls using undici's
MockAgent API.
This is useful for testing workers that make HTTP requests to other services. To
enable fetch mocking, create a
MockAgent
using the createFetchMock() function, then set this using the fetchMock
option. If you're using the
๐คน Jest Environment, use the
global getMiniflareFetchMock() function to obtain a correctly set-up
MockAgent.
import { Miniflare, createFetchMock } from "miniflare";
// Create `MockAgent` and connect it to the `Miniflare` instanceconst fetchMock = createFetchMock();const mf = new Miniflare({ modules: true, script: ` export default { async fetch(request, env, ctx) { const res = await fetch("https://example.com/thing"); const text = await res.text(); return new Response(\`response:\${text}\`); } } `, fetchMock,});
// Throw when no matching mocked request is found// (see https://undici.nodejs.org/#/docs/api/MockAgent?id=mockagentdisablenetconnect)fetchMock.disableNetConnect();
// Mock request to https://example.com/thing// (see https://undici.nodejs.org/#/docs/api/MockAgent?id=mockagentgetorigin)const origin = fetchMock.get("https://example.com");// (see https://undici.nodejs.org/#/docs/api/MockPool?id=mockpoolinterceptoptions)origin .intercept({ method: "GET", path: "/thing" }) .reply(200, "Mocked response!");
const res = await mf.dispatchFetch("http://localhost:8787/");console.log(await res.text()); // "response:Mocked response!"Subrequests
Miniflare does not support limiting the amount of subrequests. Please keep this in mind if you make a large amount of subrequests from your Worker.
Global Functionality Limits
To match the
behaviour of the Workers runtime,
some functionality, such as asynchronous I/O (fetch, Cache API, KV), timeouts
(setTimeout, setInterval), and generating cryptographically-secure random
values (crypto.getRandomValues, crypto.subtle.generateKey), can only be
performed while handling a request, not in the global scope.
KV namespaces and caches returned from Miniflare#getKVNamespace() and
Miniflare#getCaches() are unaffected by this limit, so they can still be used
in tests without setting any additional options.
instanceof, constructor and prototype Checks
Miniflare overrides instanceof checks for primitive classes like Object so
they succeed for values created both inside and outside the Miniflare sandbox
(in a different JavaScript realm). This ensures dynamic type checking often
performed by WebAssembly glue code (e.g. wasm-bindgen) always succeeds. Note
that values returned by Workers runtime APIs are created outside the Miniflare
sandbox. See
this file
for more details.
Primitive classes in this case are defined as JavaScript built-ins that can be
instantiated by something other than their constructor (e.g. literals,
functions, runtime errors):
ObjectFunctionArrayPromiseRegExpError,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError
Primitive constructor and prototype checks cannot be trapped easily and so
will fail for values created outside the Miniflare sandbox.
import { Miniflare } from "miniflare";
const mf = new Miniflare({ bindings: { OBJECT: { a: 1 }, ARRAY: new Uint8Array([1, 2, 3]), }, modules: true, script: ` export default { async fetch(request, env, ctx) { console.log({ a: 1 } instanceof Object); // โ
true console.log(new Uint8Array([1, 2, 3]) instanceof Object); // โ
true console.log({ a: 1 }.constructor === Object); // โ
true console.log(Object.getPrototypeOf({ a: 1 }) === Object.prototype); // โ
true console.log(env.OBJECT instanceof Object); // โ
true console.log(env.ARRAY instanceof Object); // โ
true console.log(env.OBJECT.constructor === Object); // โ false console.log(Object.getPrototypeOf(env.OBJECT) === Object.prototype); // โ false throw new Error("oops!"); } } `,});
try { await mf.dispatchFetch("http://localhost");} catch (e) { console.log(e instanceof Error); // โ false}By default, primitive instanceof checks outside the Miniflare sandbox will
fail for values created inside the sandbox (e.g. checking types of thrown
exceptions in tests). To fix this, pass the primitive class in from Node.js as a
custom global. Note this will cause primitive instanceof checks to fail for
values created without the constructor inside the sandbox.
const mf = new Miniflare({ modules: true, script: ` export default { async fetch(request, env, ctx) { throw new Error("oops!"); } } `,});
try { await mf.dispatchFetch("http://localhost");} catch (e) { console.log(e instanceof Error); // โ
true}