Cypress: Unable to properly stub API with cy.intercept()

Whenever I utilize the cy.intercept() function, the API fails to stub.

cy.intercept("GET", `${API}farm/list`, {
  body: {
    statusCode: 200,
    message: "Request successful",
    result: seededFarmList,
  },
});

The way I import the fixture file is as follows:

import { seededFarmList } from '../../../../../fixtures/farm'; 

This is how my API response is structured:

{
  "statusCode": 200, 
  "message": "Request successful", 
  "result": [ 
    { "id": 1 "farmName": "ABCD", },
    { "id": 2 "farmName": "EFGH", }
  ]
}

I would greatly appreciate any assistance given on this matter.

Answer №1

Ensure that the network intercept is properly set up before the application sends the api call. It's important to note that cy.intercept should be configured prior to cy.visit.

it('is correctly registered', () => {
  cy.intercept('/todos').as('todos')
  cy.visit('/')
  cy.wait('@todos')
})

In this next scenario, setting up cy.intercept after cy.visit can lead to potential failures.

 it('is registered too late and may fail', () => {
    cy.visit('/')
    cy.intercept('/todos').as('todos')
    cy.wait('@todos')
  })

Answer №2

It's a bit unclear to me why the stubbing isn't working (assuming you're referring to the server response getting through).

However, the pattern for stubbed responses has become more complex now, which might cause confusion for many users.

According to my understanding of the documentation,

In cy.route(method, url, response), the response is referred to as the body

You need to provide a response body in order to stub the matching route.

In

cy.intercept(method, url, routeHandler?)
, the routeHandler is a more intricate concept.

routeHandler (string | object | Function | StaticResponse)

Bothobject and StaticResponse are objects - Cypress differentiates between them by examining the keys within the object, as per this explanation.

If an object with no StaticResponse keys is passed, it will be treated as a JSON response body.

The keys in a StaticResponse include:

{
  fixture?: string
  body?: string | object | object[]
  headers?: { [key: string]: string }
  statusCode?: number
  forceNetworkError?: boolean
  delayMs?: number
  throttleKbps?: number
}

If you are including a statusCode, your object is considered a StaticResponse, and hence the message and result should be moved into the body section,

cy.intercept('GET',
  `${API}farm/list`,
  {
    statusCode: 200,
    body: {
      message: 'Request successful',
      result: seededFarmList
    }
  }
);

In my opinion, they may have over-complicated things slightly - the transition from StaticResponse to object based on keys seems somewhat unnecessary.


I came across an example in the sample spec file network_requests.spec.js (included in the initial run of Cypress).

beforeEach(() => {
  cy.visit('https://example.cypress.io/commands/network-requests')
})

...

let message = 'whoa, this comment does not exist'

// Stub a response to PUT comments/ ****
cy.intercept({
  method: 'PUT',
  url: '**/comments/*',
}, {
  statusCode: 404,
  body: { error: message },                         // stub returns above message
  headers: { 'access-control-allow-origin': '*' },
  delayMs: 500,
}).as('putComment')

// we have code that puts a comment when
// the button is clicked in scripts.js
cy.get('.network-put').click()

cy.wait('@putComment')

// our 404 statusCode logic in scripts.js executed
cy.get('.network-put-comment').should('contain', message)

Answer №3

After following the suggestion from @eric99, I successfully implemented stubbing in my code.

cy.intercept(
  'GET',
  'https://jsonplaceholder.typicode.com/todos/1',
  {
    statusCode: 200,
    body: {
      message: 'Request successful',
      result: ['my-data']
    }
  }
)
.as('typicode')

cy.visit('https://jsonplaceholder.typicode.com/')
cy.get('#run-button').click();

cy.wait('@typicode')
.then((interception) => {
  console.log('interception', interception)
})

Upon execution, the page displayed the stub information as expected.

{
    "message": "Request successful",
    "result": [
        "my-data"
    ]
}

Answer №5

If you are utilizing getServerSideProps() or other server-side rendering methods in Next.js, cy.intercept() will not be effective as the API calls are made on the server-side. To mock and intercept these server-side API calls, you will need to use nock within getServerSideProps() or similar server-side methods in Next.js.

For more in-depth information on this topic, check out:

Answer №6

When using template literals in the route matcher pattern, Cypress does not appear to resolve the route matcher params.

The following syntax does not work:

cy.intercept('GET', `/.*${mybaseUrl}\/something\/.*/`)

(even though the pattern is valid and displays correctly in Cypress!)

I have discovered 2 ways to make it work:

  1. Explicitly specify the URL with the routematcher parameter:
cy.intercept(
          {
            method: 'GET',
            url: `.*${mybaseUrl}\/something\/.*`
          })
  1. Use the RegExp constructor
cy.intercept('GET', new RegExp(`.*${mybaseUrl}\/something\/.*`)

It appears to be a bug in Cypress, but these two methods are effective workarounds.

Answer №7

After executing this code snippet, the API was triggered and returned successfully.

cy.intercept(
          {
            method: 'GET',
            url: `${API}farm/list`
          },

          {
            body: {
              statusCode: 200,
              message: 'Request successful',
              result: seededFarmList
            }
          }
        ).as('loadData');

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The MUI component received props that were not defined

I created a customized MUI card with the intention of applying a dark background when the darkBg prop is passed. However, I've encountered an issue where despite passing darkBg as true, the card's background remains white. To troubleshoot, I atte ...

I'm curious about how to implement textarea functionality within Angular for modeling purposes

I have a desire to utilize the model and transmit it to the server. One instance of this is sending comments. comment.model.ts export interface Comment { article_no: number; username: string; nickname: string; creatat: Date; content: string; } ...

Issue with Material UI: Unable to utilize import statement outside of a module due to Select dependency

Hello there! Here is my query: I am currently working on a project using NextJS + React with node. Everything seems to be running smoothly, except for one issue I encounter when reloading a page with a Select component from Material UI. The relevant code ...

Enhancing the NextPage Typescript Type: A Step-by-Step Guide

I'm working on a NextJS dashboard with role-based access control and I need to pass an auth object to each page from the default export. Here's an image showing an example of code for the Student Dashboard Home Page: Code Example of Student Dashb ...

Ensuring a child element fills the height of its parent container in React Material-UI

Currently, I am in the process of constructing a React Dashboard using MUI. The layout consists of an AppBar, a drawer, and a content area contained within a box (Please correct me if this approach is incorrect)... https://i.stack.imgur.com/jeJBO.png Unf ...

Discovering the proper way to infer type for tss-react withParams and create

Greetings to everyone and a huge thank you in advance for your generous help. I have a desire to utilize the tss-react library for styling, particularly because I will be implementing Material UI components. As I delve into some documentation, the latest A ...

Can anyone suggest a more efficient method for specifying the type of a collection of react components?

Picture this scenario: you are extracting data from an API and creating a list of Card components to be displayed in a parent component. Your code might resemble the following: function App() { let items = [] // How can I specify the type here to avoid ...

Creating a Route in Angular 2 for a Component other than the one initialized with the bootstrap function

I am currently in the process of working on a project involving Angular2. If you are interested in understanding why I need to do what I am about to explain, please take a look at this issue. The main component in my project is called AppComponent and it ...

How to dynamically inject HTML content from a child component into a different component using Angular 5

Is it possible to customize the content of a reusable header section based on the current route data in Angular? The header currently displays a title and description pulled from the route data property. My concern is how to dynamically inject different H ...

Is there a way to configure side={THREE.BackSide} using an external .glb file?

As a beginner in Threejs, I am trying to incorporate the use of side="THREE.BackSide" with an external model file named room.glb. My development environment consists of nextjs 13 (with typescript and app directory enabled) along with @react-three ...

Is there a way to prevent IntelliJ from creating .js files when working with .ts source code?

Working on a mixed Java/Typescript project with Maven as the build tool, I utilize the frontend-maven-plugin to successfully build from the command line. However, I am encountering an issue with IntelliJ 2018.2 where it keeps transpiling .js files for my . ...

Angular JS and TypeScript - Issue: ng:areq Invalid Argument "Argument 'XXXXXX' is not a function, received undefined"

Encountering a specific error mentioned in the title. I organized models and controllers into distinct files saved under models and controllers folders respectively. Upon trying to establish a connection between them, I received an error stating "ng:areq ...

Error TS 2322 - The property 'id' is not present in the object of type '{ id: number'

Just starting out with Angular and TypeScript. I created a model with the same properties but encountered an error and am struggling to find a solution: TS2322: Type '{ id: number; model: string; plate: string; deliveryDate: string; deadline: st ...

What is the reason behind not being able to perform a null check on an array entry in Typescript

I've got an array filled with objects that may be either null or a Gamepad: let devices: (Gamepad | null)[] = navigator.getGamepads() If the first item in the array happens to be a valid Gamepad, I need to perform a specific action: let device: Gam ...

Transferring 'properties' to child components and selectively displaying them based on conditions

This is the code for my loginButton, which acts as a wrapper for the Button component in another file. 'use client'; import { useRouter } from 'next/navigation'; import { useTransition } from 'react'; interface LoginButtonPr ...

When attempting to call an API using the Angular HttpClient, an issue is encountered

I am having trouble displaying my JSON data in my application. I have imported the HttpClientModule in app.module.ts, but I keep getting an error that says: "" ERROR Error: Cannot find a differ supporting object '[object Object]' of ty ...

Using redux action in the onPaginationChange function instead of setPaginationState in the given example for the TanStack table - is there a way to

Provided this sample Is there a way to utilize by dispatching a redux action rather than using useState - setPaginationState? onPaginationChange: state => dispatch(browseItemModalActions.setPagination(state)) An error is appearing in the console: ...

Join the Observable and formControl in Angular 4 by subscribing

My goal is to display the data retrieved from FireStore in the screen fields upon loading. However, the buildForm() function is being called before subscribing to the data, resulting in the failure to populate the screen fields with the FireStore data. pe ...

Phaser 3 game app on iOS generated with Capacitor lacks audio functionality

I have developed a basic test app using Phaser 3 (written in Typescript and transpiled with rollup) and am utilizing Capacitor to convert it into an iOS application on my Mac. This excerpt highlights the key functionality of the app: function preload () { ...

Issue with RouterLink not recognizing QueryParams

I have encountered an issue where dynamically generated URLs with queryParams inside [routerLink] are breaking routes. For example: this.url = '/question/ask?details=1' <a [routerLink]="url"> {{ data.name }}</a> Upon mouseover, the ...