March 11, 2024
Today I needed to test drive a feature which allows users to confirm their account. Users find their name in a list and tap a “👋 This is Me” button by it. When the button is tapped, they’re sent a text message with a 6-digit confirmation code and asked to enter it into a react native alert prompt, which is also shown on screen after the “👋 This is Me” button is tapped.
I was able to test that the prompt was displayed by mocking out the call to show the prompt with jest.
it("shows an alert with an input to enter the text message's confirmation code", async () => {
jest.spyOn(ReactNative.Alert, "prompt")
ERTL.renderRouter("src/app", { initialUrl: "/players/1" })
await ERTL.waitFor(() =>
ERTL.fireEvent.press(
ERTL.screen.getByTestId("This is Me Button"),
),
)
// https://reactnative.dev/docs/alert#prompt-ios
const expectedTitle = "We texted you a 6-digit code"
const expectedMessage = "Enter it here"
const expectedCallback = expect.any(Function)
const expectedType = "plain-text"
const expectedDefaultValue = ""
const expectedKeyboardType = "number-pad"
expect(ReactNative.Alert.prompt).toHaveBeenCalledWith(
expectedTitle,
expectedMessage,
expectedCallback,
expectedType,
expectedDefaultValue,
expectedKeyboardType,
)
})
This worked to test that the prompt is shown. However, testing the behavior needed when a code is actually entered into the prompt and submitted was very difficult because React Native Alerts are native components; they’re not in the view hierarchy, so there’s no way for React Native Testing Library to find the prompt and enter in text.
I don’t love adding dependencies, but after trying to test drive the behavior using React Native’s native Alert prompt for several hours, I decided to use react-native-dialog.
Here’s the skinny…
I’m adding a another dependency, which I don’t love 📉, but I think it’s worth not spending any more hours trying to figure out how to test the native alert prompt.