In a Cypress test how can I stub argument of a function

555 Views Asked by At

I am writing a Cypress integration test for a Google Optimize experiment and I would like to stub the experiment variant value provided by gtag library.

The value is provided as the argument of callback for this function:

gtag('event', 'optimize.callback', {
    name: '<experiment_id_A>',
    callback: (value) => 'unknown',
 });

How can I stub argument "value"? (without stubbing the callback return)

--

Docs for:

1

There are 1 best solutions below

0
Paolo On BEST ANSWER

I don't know much about gtag, but looking at the reference page it may be possible to stub if you are using the "external" function pattern shown on that page rather than the "inline" function you have above.

The way to stub internal functions in a React or other framework is to expose it on the window object.

function implementExperimentA(value) {
  if (value ==  '0') {
    // Provide code for visitors in the original.
  } else if (value == '1') {
    // Provide code for visitors in first variant.
  } else if (value == '2') {
    // Provide code for visitors in section variant.
  }
  ...
}

if (window.Cypress) {
  // Cypress is active
  console.log('referencing "implementExperimentA" on window')
  window.implementExperimentA = implementExperimentA;
}   

gtag('event', 'optimize.callback', {
    name: '<experiment_id_A>',
    callback: implementExperimentA
 })

Then in the test, you might set up the stub in the beforeLoad event

cy.visit('http://localhost:3000', {
  onBeforeLoad(win) {
    // Stub your functions here
    cy.stub(win, 'implementExperimentA').callsFake((realValue) => {
      const mockValue = 'abc'
      console.log(`implementExperimentA called with ${realValue}, subbing ${mockValue}`)
      return window.implementExperimentA(mockValue)
    })
  },
})

This should instantiate the stub at the earliest point in the page load, provided the reference has been set up.

Check the console.logs are firing in the right order, if not then there might be a delay in referencing the function and you can choose the stub point with cy.window().

cy.visit('http://localhost:3000')

...

cy.window().then(win => {
  // Stub your functions here
  cy.stub(win, 'implementExperimentA').callsFake((realValue) => {
    const mockValue = 'abc'
    console.log(`implementExperimentA called with ${realValue}, subbing ${mockValue}`)
    return window.implementExperimentA(mockValue)
  })
})