Cypress Network Stubbing

Network stubbing replaces a real server response with a fake one you control. This technique helps test how a page behaves under specific conditions without depending on a real backend. This topic explains how stubbing works in Cypress.

The cy.intercept Command

The cy.intercept command watches for network requests matching a specific pattern and can replace their response.

cy.intercept('GET', '/api/products', {
  statusCode: 200,
  body: [{ id: 1, name: 'Test Product' }]
})
cy.visit('/shop')

This test tells Cypress to respond with fake product data whenever the page requests the products endpoint.

A Simple Way to Picture It

Think of network stubbing as replacing a real actor with a stunt double for a dangerous scene. The audience sees the same scene play out, but a controlled substitute performs the risky part instead. Stubbing substitutes a real server response with a safe, predictable fake one.

Why Teams Use Stubbing

Real servers can be slow, unreliable, or unavailable during testing. Stubbing removes this dependency, letting tests run consistently regardless of backend status. It also allows testing rare scenarios, such as server errors, that are hard to trigger naturally.

Stubbing Flow Diagram

Page requests /api/products
      |
      v
cy.intercept catches the request
      |
      v
Cypress returns the fake response instead of calling the real server
      |
      v
Page renders using the fake data

Simulating an Error Response

Stubbing makes it easy to test how a page handles a failed request.

cy.intercept('GET', '/api/products', {
  statusCode: 500,
  body: { error: 'Server error' }
})
cy.visit('/shop')
cy.contains('Something went wrong').should('be.visible')

This test confirms the page shows a proper error message when the server fails.

Using Fixtures with Stubbing

Stubbed responses often pull data from a fixture file instead of writing the response directly in the test.

cy.intercept('GET', '/api/products', { fixture: 'products.json' })

This approach keeps the test file shorter while allowing the fixture data to be reused elsewhere.

Waiting for Stubbed Requests

Aliasing an intercepted request lets a test wait until the stubbed response actually gets used.

cy.intercept('GET', '/api/products', { fixture: 'products.json' }).as('getProducts')
cy.visit('/shop')
cy.wait('@getProducts')
cy.contains('Test Product').should('be.visible')

Stubbing Dynamic Responses

Cypress can also generate a response dynamically using a function instead of a fixed object.

cy.intercept('GET', '/api/user', (req) => {
  req.reply({ statusCode: 200, body: { name: 'Dynamic User' } })
})

This pattern suits situations where the response needs to change based on request details.

Spying Without Stubbing

Sometimes a test only needs to observe a request without changing its response. Calling cy.intercept without a response argument allows the real request to continue while still tracking it.

cy.intercept('GET', '/api/products').as('getProducts')
cy.visit('/shop')
cy.wait('@getProducts').its('response.statusCode').should('equal', 200)

When Not to Stub

Stubbing every request removes real backend verification from your test suite entirely. Some tests should still run against a real backend to confirm actual integration works correctly. A balanced approach uses stubbing for edge cases and real requests for core integration checks.

Key Points

  • cy.intercept catches network requests and can replace their response.
  • Stubbing helps test error scenarios that are hard to trigger naturally.
  • Fixture files often supply the fake data used in a stubbed response.
  • Aliases let a test wait for a stubbed request to complete.
  • Some tests should still use real requests to verify actual integration.

Leave a Comment

Your email address will not be published. Required fields are marked *