Cypress Network Interception & Mocking
Network interception is one of Cypress's most powerful capabilities — it lets you intercept, inspect, modify, and stub any HTTP request the browser makes. This enables testing of loading states, error conditions, slow networks, and API edge cases without needing a specific backend state. It's the foundation of fast, reliable frontend testing.
30 min•By Priygop Team•Updated 2026
cy.intercept() — Intercept, Stub, and Spy on Network Requests
cy.intercept() — Intercept, Stub, and Spy on Network Requests
// ══════════════════════════════════════════════════════════════
// SCENARIO: Test how the UI handles different API responses
// ══════════════════════════════════════════════════════════════
// ── 1. STUB — Return fake response (no real API call made) ────
it('shows product list when API returns data', () => {
cy.intercept('GET', '/api/products', {
statusCode: 200,
body: [
{ id: 1, name: 'iPhone 15', price: 999 },
{ id: 2, name: 'MacBook Air', price: 1299 },
]
}).as('getProducts'); // Alias for later reference
cy.visit('/products');
cy.wait('@getProducts'); // Wait for the intercepted request
cy.get('.product-card').should('have.length', 2);
cy.get('.product-card').first().should('contain', 'iPhone 15');
});
// ── 2. STUB — Simulate API error ──────────────────────────────
it('shows error message when API returns 500', () => {
cy.intercept('GET', '/api/products', {
statusCode: 500,
body: { error: 'Internal Server Error' }
}).as('getProductsError');
cy.visit('/products');
cy.wait('@getProductsError');
cy.get('.error-banner').should('be.visible');
cy.get('.error-banner').should('contain', 'Failed to load products');
cy.get('.retry-button').should('be.visible');
});
// ── 3. STUB — Simulate slow network (loading state test) ──────
it('shows loading spinner while data is being fetched', () => {
cy.intercept('GET', '/api/products', (req) => {
req.reply((res) => {
res.setDelay(3000); // 3-second delay
res.send({ statusCode: 200, body: [] });
});
}).as('slowProducts');
cy.visit('/products');
cy.get('.loading-spinner').should('be.visible');
cy.wait('@slowProducts');
cy.get('.loading-spinner').should('not.exist');
});
// ── 4. SPY — Let real request through, just observe it ────────
it('sends correct payload when submitting order', () => {
cy.intercept('POST', '/api/orders').as('createOrder');
cy.visit('/checkout');
cy.get('[data-testid="place-order"]').click();
// Inspect the actual request that was sent
cy.wait('@createOrder').then((interception) => {
expect(interception.request.body.items).to.have.length(1);
expect(interception.request.body.totalAmount).to.equal(79.99);
expect(interception.response.statusCode).to.equal(201);
});
});
// ── 5. MODIFY RESPONSE — Partial transform of real response ───
it('adds items to real response for testing UI with full list', () => {
cy.intercept('GET', '/api/products', (req) => {
req.reply((res) => {
res.body.push({ id: 999, name: 'Test Product', price: 0 });
res.send();
});
});
});Diagram
Loading diagram…
Mock at boundaries.
Common Mistakes
- Not aliasing intercepts — cy.wait('@alias') is the correct way to wait for a request; without aliases, you can't reliably wait for specific calls
- Stubbing everything by default — over-stubbing makes tests test the stub, not the real app behavior; spy on real calls when possible
- Not testing error edge cases — network interception's biggest value is testing error conditions (500, 404, timeout) that are hard to trigger on real APIs
- Forgetting that stubs are test-local — cy.intercept() stubs only apply to the current test; they don't carry over between tests
Key Takeaways
- Network interception is one of Cypress's most powerful capabilities — it lets you intercept, inspect, modify, and stub any HTTP request the browser makes.
- Not aliasing intercepts — cy.wait('@alias') is the correct way to wait for a request; without aliases, you can't reliably wait for specific calls
- Stubbing everything by default — over-stubbing makes tests test the stub, not the real app behavior; spy on real calls when possible
- Not testing error edge cases — network interception's biggest value is testing error conditions (500, 404, timeout) that are hard to trigger on real APIs