Detox
Detox copied to clipboard
Mocking post/get requests with different responses
Description
Hello, I can't see any documentation on how to mock post/get requests and pass in different responses. Please can you point me to where I'll find how to do this so I can test different happy/sad paths in my application? Thanks.
Your environment
Detox version: React Native version: Node version: Device model: OS: Test-runner (select one): jest / other
@ElliotWood13 there's no designated Detox API for mocking network requests directly, however - you can mock the module that runs your network requests, see our mocking guide for guidance.
@asafkorem would this be static though? sounds like they are asking for dynamic mocks
@asafkorem @d4vidi how hard is it for us to set up a global proxy server forwarding on a device? If we could find a good proxy implementation with some sweet mocking API and combine it with the said device.enableProxy('http://localhost:3333')
API - that could enable this scenario very easily.
yeah exactly @Sid-Turner-Ellis. Ideally being able to mock like in Jest with a resolved/rejected response would be great.
My requirements are different to yours (https://github.com/wix/Detox/issues/3996) but it sounds like you just need to set up a mock server that you can post the desired responses to before the request:
- In your detox test, make a post request to your server describing what its next return value should be
- Mock the API url with the mock server url with a .mock.js file
- The response should be the value mocked
The same logic would follow for checking the requests, you could look into Nock or https://www.mocks-server.org/ if you want something more fleshed out.
I would recommend really thinking whether you should do this though - I'm not saying you shouldn't but whilst asking my question I realised I was trying to use the e2e tests to test things that my unit/integration tests should cover
@asafkorem @d4vidi how hard is it for us to set up a global proxy server forwarding on a device? If we could find a good proxy implementation with some sweet mocking API and combine it with the said
device.enableProxy('http://localhost:3333')
API - that could enable this scenario very easily.
That's definitely an idea that deserves research. I estimate we might be able to employ nock
to work inside the app but we would still likely have to allow for a means to configure or preconfigure it through the test code. Another caveat with nock would be that we will not be mocking pure native calls, meaning we would have to resort to native tweaks. Anyways, definitely doable, though probably not entirely trivial.
@d4vidi, here's my take at it:
Support mocking network requests dynamically
Description
This feature request aims to add support for mocking network requests (GET, POST, etc.) within Detox by setting up a global proxy server for both Android and iOS devices/emulators. This will allow developers to easily test different scenarios and edge cases in their applications by simulating various responses from API endpoints.
Proposed Solution
The proposed solution consists of two main components:
-
Setting up a global proxy server on the testing device/emulator:
- For Android, utilize adb to configure the global proxy settings on the emulator, e.g.:
adb shell settings put global http_proxy 192.168.1.10:8888 adb shell settings put global http_proxy :0
- For iOS simulators, set up a global proxy on the macOS host using the
networksetup
command:
networksetup -setwebproxy "Wi-fi" 127.0.0.1 8080 networksetup -setwebproxystate "Wi-fi" off networksetup -getwebproxy "Wi-Fi"
-
Showcasing
http-mitm-proxy
(or similar) library to intercept and manipulate network requests:-
http-mitm-proxy
is a Node.js library for creating an HTTP man-in-the-middle proxy. We can use this library to intercept and manipulate network requests and responses on the fly. - Unfortunately, it lacks some sleek DSL for request/response manipulation, so we might look for alternatives or create a custom wrapper around it, e.g.:
import proxy from 'some-proxy-library'; beforeAll(async () => { await proxy.listen(9001); await device.enableProxy('http://localhost:9001'); }); it('should load into new login screen if A/B test is on', async () => { await proxy.get('http://api.example.com/ab').mockResponse({ 'new_login_screen': true, }); await device.launchApp({ newInstance: true }); await expect(element(by.id('NEW_LOGIN_SCREEN'))).toBeVisible(); });
-
@noomorph Wow, that's well thought out!
And it make perfect sense, up to the point when you realize you'd be redirecting all of the app's network calls through the host 😞 Of course, that's perfectly fine for locally hosted emulators, but - considering that app_network_calls_count >> detox_mock_config_calls_count
it may not be so great for remote ones.
What I was aiming for is an inherent proxy in Detox that would take over the JS network or the native one, so that mocked calls would never leave the device. We can attempt to explore both ways and decide!
@d4vidi I think I understand your direction but it won't be without drawbacks as well. Native components, web views might still run network traffic bypassing such a MiTM solution in the layer of RN/Hermes. Feel free to write a similar vision document for the feature. Maybe someone could take it for a guild week. I just think that as a task it won't be friendly to JS-only developers coming for a short break from their daily routine.
@valentynberehovyi if you happen to have a minute to glance over @d4vidi 's idea, do you have any two cents to add (regarding feasibility of network interceptor on React Native level, substituting fetch provided to Hermes JS engine)?
Amit refers to the problem with running cloud Android devices from an arbitrary place (e.g. Genymotion SaaS). Forcing the device to conduct all network communication via tester's machine might be inefficient, indeed.
web views might still run network traffic bypassing such a MiTM solution in the layer of RN/Hermes
That's true indeed.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest Detox and report back.
Thank you for your contributions!
For more information on bots in this repository, read this discussion.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest Detox and report back.
Thank you for your contributions!
For more information on bots in this repository, read this discussion.
The issue has been closed for inactivity.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest Detox and report back.
Thank you for your contributions!
For more information on bots in this repository, read this discussion.
The proposals from @noomorph and @d4vidi are undoubtedly sophisticated. However, I believe we must step back and consider the diverse mocking needs, ranging from file I/O and databases to third-party integrations.
Let's prioritize simplicity. We need a straightforward, adaptable solution that addresses a wide spectrum of mocking scenarios. Perhaps introducing a detox.mock()
method, which allows for specific test-time overrides, could be the solution (runtime JS bundling).
I'm not sure if there's any mocking need that isn't covered by this approach.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you believe the issue is still relevant, please test on the latest Detox and report back.
Thank you for your contributions!
For more information on bots in this repository, read this discussion.
Hello,
with unstable_enableSymlinks
support, will it be possible to mock network calls inside the E2E test suite?
Please give an example of this.
Might be a silly question, sorry for that 🙏
@noomorph
reference link: https://github.com/wix/Detox/pull/4208#issuecomment-1875814267
@marufMunshi the unstable_enableSymlinks
was previously required to include self-test e2e into the Detox repository, and it was never needed for the feature itself. Anyway, it is no longer a blocker.
Backdoor feature won't help directly with mocking network calls – it just might make certain things around mocking easier to implement. For mocking network, you'd need to monkey-patch fetch
and listen to events from Detox regarding how to response to certain url patterns. This kind of mock would deserve its own npm library, and also I don't see how easily to configure on-app-launch requests-responses within this hypothetical detoxBackdoor-based flow. Not sure if you really need that.