Testing
You don't need an HTTP interceptor
Need to write tests? Use libraries like msw
or nock
? Well you don't need
them with starfx
. If the mdw.fetch()
middleware detects ctx.response
is
already filled then it skips making the request. Let's take the update user
endpoint example and provide stubbed data for our tests.
1import { fireEvent, render, screen } from "@testing-library/react";
2import { useDispatch, useSelector } from "starfx/react";
3import { db } from "./schema.ts";
4import { updateUser } from "./user.ts";
5
6function UserSettingsPage() {
7 const id = "1";
8 const dispatch = useDispatch();
9 const user = useSelector((state) => db.users.selectById(state, { id }));
10
11 return (
12 <div>
13 <div>Name: {user.name}</div>
14 <button onClick={() => dispatch(updateUser({ id, name: "bobby" }))}>
15 Update User
16 </button>
17 </div>
18 );
19}
20
21describe("UserSettingsPage", () => {
22 it("should update the user", async () => {
23 // just for this test -- inject a new middleware into the endpoint stack
24 updateUser.use(function* (ctx, next) {
25 ctx.response = new Response(
26 JSON.stringify({ id: ctx.payload.id, name: ctx.payload.name }),
27 );
28 yield* next();
29 });
30
31 render(<UserSettingsPage />);
32
33 const btn = await screen.findByRole("button", { name: /Update User/ });
34 fireEvent.click(btn);
35
36 await screen.findByText(/Name: bobby/);
37 });
38});
That's it. No need for http interceptors and the core functionality works exactly the same, we just skip making the fetch request for our tests.
What if we don't have an API endpoint yet and want to stub the data? We use the
same concept but inline inside the updateUser
endpoint:
1export const updateUser = api.post<{ id: string; name: string }>(
2 "/users/:id",
3 [
4 function* (ctx, next) {
5 ctx.request = ctx.req({
6 body: JSON.stringify({ name: ctx.payload.name }),
7 });
8 yield* next();
9 },
10 function* (ctx, next) {
11 ctx.response = new Response(
12 JSON.stringify({ id: ctx.payload.id, name: ctx.payload.name }),
13 );
14 yield* next();
15 },
16 ],
17);
Wow! Our stubbed data is now colocated next to our actual endpoint we are trying to mock! Once we have a real API we want to hit, we can just remove that second middleware function and everything will work exactly the same.