skip to Main Content

I want to spy on a function which is defined in a separate file and called by multiple react components.

for example I have this test.js file:

export const func = {
  call: (e) => console.log(e),
};

This is imported by multiple React components and i want to spy on this function with cypress but its never called:

import { func } from "../../src/test";

describe("template spec", () => {
  it("calls func.call", () => {    
    cy.visit("/");
    cy.spy(func, "call");
    //some more code ...
    expect(func.call).to.be.called
  });
});

The goal of my test is to validate the network traffic from my app to the backend and backwards over rest and socket.io. Because its necessary that the app can be used without the real backend for presentation and testing purpose i mocked the fetch function and socket events to simulate the backend which can be enabled by an environment variable. And its required that the test can run without the backend running. The problem is on the one hand that i need a possibility to test my socket.io traffic which is not possible with cypress like i read and on the other hand that cy.intercept for fetch is not working as expected. I manged to intercept the fetch calls and redirect them to my mockfunction but it seems that the original fetch body is already kind of serilized and i can not easily get the original fetch body. This is especially tricky when it comes to formdata body.

I’m new to testing with cypress, so i might have misunderstood the concept of spying. What am i doing wrong?

2

Answers


  1. To test the WebSocket, There is a library for Cypress

    https://github.com/lensesio/cypress-websocket-testing

    The same is also listed on the Cypress plugin webpage.

    https://docs.cypress.io/plugins

    Here you’ll find many plugins which will help you with many of your future problems.

    Hope this helps.

    Login or Signup to reply.
  2. I can answer the question about your spy.

    When you import func inside the test you are getting a different instance of the function to the one the app is using.

    If you want to successfully spy on it, you must pass the same instance from the app to the test.

    The accepted way to do that is to put func on the window object. For example, in App.js in the React code

    import React from 'react';
    import { func } from "../../src/test"
    
    if (window.Cypress) {   // check if Cypress is running
      window.func = func
    }
    
    function App() {
      const greeting = 'Hello Function Component!';
    
      return <h1>{greeting}</h1>;
    }
    
    export default App;
    

    Now in your test, you will successfully spy on func like this

    it("calls func.call", () => {    
    
      cy.visit('/', {
        onBeforeLoad: (window) => {          // IMPORTANT spy must be set first!!! 
          cy.spy(window, 'func').as('func')  // spy on func property, setting an alias
      })
    
      //some more code ...
    
      cy.get('@func').should('have.been.called')
    })
    

    Reference: for more examples Bahmutov – Spies, Stubs & Clocks

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search