react-nativetestingdetoxnock

Is it possible to mock responses during a detox end-to-end test


I'm currently making a react-native mobile application. I try to test my login button and fields and want to test the logic of moving to the account screen upon login.

Currently I got this as my testcase:

import {clickAccountButton} from "./Navigation";
//API
import nock from "nock";
import {API_URL} from "@env";
import {axiosPost} from "../app/config/api";

jest.useFakeTimers();

describe('LoginScreen tests', function () {
  beforeAll(async () => {
    await device.launchApp();
  });

  it('should show the login screen', async () => {
    await clickAccountButton();
    await expect(element(by.id('loginScreen'))).toBeVisible();
  });

  it('should have the header', async () => {
    await expect(element(by.id('header'))).toBeVisible();
  });

  it('should contain email and password form field', async () => {
    await expect(element(by.id('email'))).toBeVisible();
    await expect(element(by.id('password'))).toBeVisible();
  });

  it('should contain the login and forgotten password buttons', async () => {
    await expect(element(by.id('loginSubmit'))).toBeVisible();
    await expect(element(by.id('forgotPassword'))).toBeVisible();
  });

  it('should navigate to ForgotPassword onPress', async () => {
    await element(by.id('forgotPassword')).tap();
    await expect(element(by.id('forgotPasswordScreen'))).toBeVisible();
    //Click the account button again to return to the login screen
    await clickAccountButton();
  });

  it('should login successfully', async () => {
    //Give the following response to the next httpRequest
    nock(`${API_URL}`)
        .post('/api/v1/auth/login')
        .reply(200, {
          loggedIn: true,
          user: {
            id: 1,
          }
        }).persist();

    await element(by.id('email')).replaceText('hello@email.com');
    await element(by.id('password')).replaceText('foobar');
    await element(by.id('loginSubmit')).tap();
    

    //Double check: Check if the view with testID 'welcomeScreen' is showing
    //and the input field with testID 'email' is gone
    await expect(element(by.id('accountScreen'))).toBeVisible();
    await expect(element(by.id('email'))).not.toBeVisible();
  });
});

I expect the 'should login successfully' case to succeed because i'm intercepting the request and nock sends a response. This is not the case though. Instead it just does the actual request to my local API server which I don't want to use. Cause I don't want actual login details in my test.

Does anyone know how to handle this? Thanks in advance!


Solution

  • Jest and the app under test run in separate processes so normal Jest mocking techniques such as Nock won't work. Have a look at the mocking guide for Detox.

    If you have a module such as apiClient.js in your app then you can mock that with something like apiClient.mock.js.