I'm trying to write a component test for CheckBox in an open source nextjs project I'm helping out with. However, I keep getting the following error Screenshot of cypress run.
The test runner seems to indicate that everything is stubbed ok.
Anyone have an any idea what I'm doing wrong?
Read the docs, googled, and used copilot. I've only just begun learning cypress so I'm sure it's a simple fix that I'm missing due to a lack of experience.
The basic problem is that import { addCardToDeck, removeCardFromDeck } from '@api'
in the test is creating a different instance of these methods to the ones used in the component.
You can pass the imports from the app to the test as a property window
. This means you have to add test-specific code to the component, but you can check if the component is in "test mode".
Here's what that looks like
CheckBox.tsx
//import { addCardToDeck, removeCardFromDeck } from '@api' // import the module here
import * as apiModule from '@api' // and spread the methods
// inside the component
// check for "test mode" by checking for Cypress property of window
if (window.Cypress) {
const { addCardToDeck, removeCardFromDeck } = apiModule
window.apiModule = {addCardToDeck, removeCardFromDeck}
}
const CheckBox = ({ card }: CheckBoxProps) => {
// destructure here - if testing, use the mock versions
let { addCardToDeck, removeCardFromDeck } = window.Cypress ? window.apiModule : apiModule
...
CheckBox.cy.tsx
it('adds card to deck when clicked and card is not selected', () => {
const apiModule = window.apiModule // don't need cy.window() for component tests
cy.stub(apiModule, 'addCardToDeck').as('addCardToDeck').resolves()
cy.stub(apiModule, 'removeCardFromDeck').as('removeCardFromDeck').resolves()
cy.mount(<CheckBox card={mockCard} />)
cy.get('.checkbox').click()
cy.get('@addCardToDeck').should('have.been.calledWith', mockCard)
})
Notes
I think you are running NextJs, so window
won't exist at runtime - if so amend the test-mode check to (window && window.Cypress)
There should also be a way to do this by using a wrapper component in cy.mount()
, if I can get it working I'll post that version.