Fix MSW GraphQL Mock – GraphQL Query Not Mocked
DodaTech
Updated 2026-06-24
3 min read
In this tutorial, you'll learn about Fix MSW Graphql Mock. We cover key concepts, practical examples, and best practices.
You set up MSW with GraphQL handlers, but queries and mutations pass through to the real GraphQL server. The console logs: "[MSW] Warning: captured a request without a matching request handler" for a GraphQL request.
Wrong ❌
// mocks/handlers.js
import { graphql, HttpResponse } from 'msw';
export const handlers = [
graphql.query('GetUser', ({ variables }) => {
return HttpResponse.json({
data: {
user: null,
},
});
}),
];
The query:
```<a href="/apis/graphql/">graphql</a>
query GetUser($id: ID!) {
user(id: $id) {
id
name
}
}
MSW matches the operation by name — `GetUser`. The handler returns `{ data: { user: null } }`, but the component expects `{ id, name }`. The component crashes or shows empty data.
## Right ✅
```javascript
// mocks/handlers.js
import { graphql, HttpResponse } from 'msw';
export const handlers = [
// ✅ Query handler with proper response shape
graphql.query('GetUser', ({ variables }) => {
const { id } = variables;
return HttpResponse.json({
data: {
user: {
id,
name: 'Alice',
email: 'alice"@example".com',
__typename: 'User',
},
},
});
}),
// ✅ Mutation handler
graphql.mutation('UpdateUser', async ({ variables }) => {
const { id, name } = variables;
return HttpResponse.json({
data: {
updateUser: {
id,
name,
__typename: 'User',
},
},
});
}),
];
**Mock GraphQL errors:**
```<a href="/programming-languages/javascript/">javascript</a>
<a href="/apis/graphql/">graphql</a>.query('GetUser', () => {
return HttpResponse.json({
errors: [
{
message: 'User not found',
extensions: { code: 'NOT_FOUND' },
},
],
});
});
**Use variables in responses:**
```javascript
graphql.query('GetUser', ({ variables }) => {
const users = {
1: { id: '1', name: 'Alice' },
2: { id: '2', name: 'Bob' },
};
return HttpResponse.json({
data: { user: users[variables.id] ?? null },
});
});
**Debug — log incoming queries:**
```<a href="/programming-languages/javascript/">javascript</a>
import { <a href="/apis/graphql/">graphql</a>, HttpResponse } from 'msw';
<a href="/apis/graphql/">graphql</a>.query('GetUser', ({ variables, query }) => {
console.log('MSW intercepted:', query, variables);
return HttpResponse.json({ data: { user: null } });
});
**Multiple operations in one handler:**
```<a href="/programming-languages/javascript/">javascript</a>
<a href="/apis/graphql/">graphql</a>.operation(async ({ query, variables }) => {
if (query.includes('GetUser')) {
return HttpResponse.json({ data: { user: { id: '1' } } });
}
if (query.includes('GetPosts')) {
return HttpResponse.json({ data: { posts: [] } });
}
return HttpResponse.json({ errors: [{ message: 'Unknown operation' }] });
});
## Root Cause
MSW <a href="/apis/graphql/">GraphQL</a> interception matches by **operation name** (e.g., `GetUser`). If the handler name doesn't match the operation name in the <a href="/apis/graphql/">GraphQL</a> document, the request isn't intercepted. Also, the response must match the <a href="/apis/graphql/">GraphQL</a> response shape (`{ data: ... }` or `{ errors: ... }`).
## Prevention
- Use `<a href="/apis/graphql/">graphql</a>.operation()` to catch **all** <a href="/apis/graphql/">GraphQL</a> requests and route by operation name internally.
- Keep the mock response shape consistent with the schema — use the same `__typename` and field names.
- Log `variables` in the handler to see what the client sends.
- Use `server.use()` for one‑off overrides in specific tests.
## Common Mistakes with <a href="/apis/graphql/">graphql</a> mock
1. **Forgetting that lazy evaluation defers computation until the value is forced, causing space leaks with unevaluated thunks**
2. **Using `return` to exit a function early instead of wrapping a pure value in the monad**
3. **Mixing let bindings with <- bindings in do notation, producing type errors**
These mistakes appear frequently in real-world MSW code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
## Practice Exercise
**Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.**
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
## FAQ
<details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Can MSW mock subscriptions?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: MSW v2+ supports <a href="/apis/graphql/">GraphQL</a> subscriptions over <a href="/apis/websocket/">WebSocket</a>. Use <code><a href="/apis/graphql/">graphql</a>.subscription()</code>.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: What if my <a href="/apis/graphql/">GraphQL</a> endpoint is different from `/<a href="/apis/graphql/">graphql</a>`?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: MSW intercepts by operation name, not path. It works with any endpoint.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: How do I mock a <a href="/apis/graphql/">GraphQL</a> error (e.g., 500)?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Return <code>HttpResponse.json({ errors: [...] }, { status: 500 })</code>.</p>
</div></details><details style="margin-bottom:12px;border:1px solid #e2e8f0;border-radius:10px;overflow:hidden"><summary style="cursor:pointer;padding:14px 18px;font-weight:600;font-size:1.05rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;color:#1e293b">**Q: Can I use MSW with Apollo Client cache?**</summary><div style="padding:14px 18px;color:#475569;line-height:1.7;background:#fff"><p>A: Yes — MSW intercepts at the network level, so Apollo's cache is bypassed. The response is treated as a real network response.</p>
</div></details>
---
*<a href="/apis/graphql/">GraphQL</a> mocking is covered in the [DodaTech MSW for <a href="/apis/graphql/">GraphQL</a> course](https://dodatech.com/courses/msw).*
← Previous
MQTT Mutual TLS Handshake Fails
Next →
Fix MSW Handler Not Caught – Request Not Intercepted
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro