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 it's 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 it's 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 mock function but it seems that the original fetch body is already kind of serialized and I cannot 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?
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