Mock Your Backend with Cypress

Brett Cassette
InstructorBrett Cassette
Share this video with your friends

Social Share Links

Send Tweet
Published 5 years ago
Updated 4 years ago

Using cy.server, cy.route, and cy.wait, we can intercept requests to our real backend, and return known mock responses.

The pros of using this approach:

  • It's much faster than interacting with the real backend
  • Doesn't need to seed data to the backend
  • Easy control of requests and responses
  • Can mock network delay and failure


  • No guarantee the stubs match the real backend responses
  • Not full end-to-end testing

Recommended Homework:

  • Mock the route to create a new todo, and reply with a 200
  • Mock the route to edit an existing todo, and reply with a 200

Instructor: [00:00] In this example, we're going to talk about mocking the backend. We can discover the reason we need to mock the backend by visiting our real page at localhost:5000. Let's switch over to Chrome.

[00:13] Here, we can edit our first to-do. Let's make this Hello, World with a bunch of Zs.

[00:20] Now let's return to Cypress, refresh, and we'll see that we have a failing test. That's because we expected this to have the text Hello, World, but it's actually using the real data from our real backend, which we've just changed.

[00:38] There are two strategies we can use to address this. One is stubbing all of our network requests. The other is that we can interact with the real backend, but we have to have a database seeding abstraction, as well as a totally isolated testing environment.

[00:54] In this lesson, we're just going to talk about the first one, and in later lessons, we'll show how to seed the database. To start, let's tell Cypress simply that we want to begin stubbing network requests.

[01:05] To do that, we can call cy.server. By default, this doesn't stub out any requests. They'll all still continue to pass through to the backend, but we do need to call cy.server before we can start mocking routes or spying on them.

[01:21] To actually start mocking our routes, we need to know what we need to mock. Let's go back to Cypress and take a look at our XHR request. We see that we perform a GET to api/todos. That's hitting the real backend. Let's mock that out.

[01:37] Let's call cy.route to that endpoint, api/todos. By default, this is a GET request.

[01:44] Next, we'll return an array of hashes. We can actually see what's in our real backend by looking in db.json.

[01:52] Let's go ahead and just copy this out and paste it in. We did expect this not to have so many Zs or any at all, so let's save it.

[02:08] Next, we have to cy.wait for this route to load, which means that we have to give it an alias. We can say asPreload and we'll wait for @preload. We'll save it and return.

[02:24] Now we can see that we waited for our preload, which returned our mock data and made all our tests pass again. We can also do a deep dive on this request by clicking on the preload, opening our console, and checking our XML HTTP request, where we can see everything like status code, response, body and headers, and we can inspect this to make sure it's what we just sent. It is.

Joshua Travis
Joshua Travis
~ 5 years ago

For some reason, cy.route() doesn't want to use my configured baseUrl by default. So I'm having to use Cypress.config().baseUrl to get it to work. Any thoughts as to why?

Markdown supported.
Become a member to join the discussionEnroll Today