reactjstypescriptcypressstubbing

Cypress: Not able to stub with a basic example. What might i be missing?


For some reason, I am not able to stub this here. I have reduced my code to almost exactly this here. This should work according to the docs, but I'm wondering if I'm missing a finer detail of typescript / react hooks? That doesn't feel at all like the case but who knows. Thanks ahead of time if you're reading this and taking up your time. I appreciate what you do. Here's my example:

// connection.ts (the method to stub)

export const connectFn = async () => {
  return 'i should not be here'
}
// ./reactHook.ts

import { connectFn } from './connection'

export const useMyHook = () => {
  const handleConnect = async () => {
    const result = await connectFn()
    console.log(result)
    // expected: 'i have been stubbed!'
    // actual: 'i should not be here
  }

  return {
    handleConnect
  }
}
// ./App.ts

export const App = () => {
  const { handleConnect } = useMyHook()
  return <button onClick={handleConnect}>Connect</button>
}
// ./cypress/integration/connection.spec.ts

import * as myConnectModule from '../../connection'

describe('stub test', () => {
  it('stubs the connectFn', () => {
    cy.stub(myConnectModule, 'connectFn').resolves('i have been stubbed!')
    cy.get('[data-testid=connect-btn]').click()
    // assertions about the view here...
  })
})

I thought I understood the cypress and Sinon docs pretty well. I have read that cypress needs an object to a stub from and not the named export directly - hence the * as an import. I have also tried every which way to export it as well. I used their example from the docs directly to no avail. I then thought it may be a typescript issue but it doesn't seem to be the case. I have reduced my actual code to pretty much this example here. I have even removed everything but the logs for testing and I'm still not getting it.


Solution

  • To stub successfully you need to stub (replace) the same instance.

    In reactHook.ts

    import { connectFn } from './connection'
    
    if (window.Cypress) {
      window.connectFn = connectFn
    }
    

    In the test

    cy.window().then(win => {
      cy.stub(win, 'connectFn').resolves('i have been stubbed!')
      cy.get('[data-testid=connect-btn]').click()
      ...
    }}
    

    BTW useMyHook implies a React hook, if so you may need a cy.wait(0) to release the main JS thread and allow the hook to run.