Recently I have shown how to verify that a React Native application in bahmutov/expo-cypress-examples opens the help URL when the user clicks on the help link. The application used the following code:
1 | import * as WebBrowser from 'expo-web-browser'; |
The application was tested while running in the browser, served by the Expo tool. I guessed that in the browser, the second window is opened using window.open
called somewhere inside the expo-web-browser
module. Thus I could prevent the second browser window from opening using the test code below:
1 | it('opens the help link in the browser', () => { |
The test works and confirms the application calling the window.open
with expected arguments.
You can see me write the above test in the video Testing WebBrowser.openBrowserAsync. Except the title is wrong - we are not confirming that the method WebBrowser.openBrowserAsync
is called, right? We are confirming window.open
is called. Why can't we directly confirm the WebBrowser.openBrowserAsync
method call?
Stubbing WebBrowser.openBrowserAsync - does not work
Let's try stubbing the web browser method directly. We can expose the imported WebBrowser
object from the application, and the test code can access it.
1 | import * as WebBrowser from 'expo-web-browser'; |
From the test we can access the window.WebBrowser.openBrowserAsync
method before clicking the link.
1 | it('calls openBrowserAsync', () => { |
We can see the second browser window open - so our stub did NOT work. Let's look at the property we are trying to stub.
1 | cy.visit('/') |
When the test runs, open the browser DevTools console, which shows:
1 | {set: undefined, enumerable: true, configurable: false, get: ƒ} |
The property openBrowserAsync
cannot be overwritten by the cy.stub
method unfortunately. We will need to modify the application code to make this property stubbable.
Stub the wrapper method
We can solve our problem by creating an intermediate object with stubbable methods.
1 | import * as _WebBrowser from 'expo-web-browser'; |
The wrapper WebBrowser
that spreads the methods from the imported expo-web-browser
module is the key. Let's run the test again.
Beautiful.