Jest spyOn does not mock external function used in source file

23 Views Asked by At

The following is my source code and test code respectively

// Grid.tsx

import React from "react";
import { View, StyleSheet, useWindowDimensions } from "react-native";


interface GridProps {
    borders?: boolean;
    cellPressHandler: (row: number, col: number) => void;
    gameState: GameState;
}

const Grid: React.FC<GridProps> = ({ borders = false, cellPressHandler, gameState }) => {

    const { height, width } = useWindowDimensions();
    
    ...

    const gridStyle = StyleSheet.create({

        dimension: {
            height: width < height ? width * 0.9 : height * 0.9,
            width: width < height ? width * 0.9 : height * 0.9,
        }

    })

    return (
        <View
            accessible={true}
            accessibilityLabel="tic tac toe grid"
            style={gridStyle.dimension}
        >{grid}</View>
    );

}

export default Grid;
// Grid.test.tsx

/**
 * @format
 */

import { describe, it, expect, afterEach, jest } from '@jest/globals';
import { render, screen, userEvent } from "@testing-library/react-native";

import { GameState } from '../../src/types';
import { Grid } from '../../src/components';

import * as RN from "react-native";

...

describe("height and width", () => {

    afterEach(() => {
        jest.restoreAllMocks();
    })

    it("should be 90% of width when in portrait", () => {

        jest.spyOn(RN, "useWindowDimensions").mockReturnValue({
            height: 400,
            width: 100,
            scale: 1,
            fontScale: 1
        })

        const testGameState: GameState = [
            [{}, {}, {}],
            [{}, {}, {}],
            [{}, {}, {}]
        ]

        render(<Grid
            cellPressHandler={() => { }}
            gameState={testGameState}
        />);

        const sample = screen.getByLabelText("tic tac toe grid");

        expect(sample).toHaveStyle({ height: 90, width: 90 });
    });

    it("should be 90% of height when in landscape", () => {

        jest.spyOn(RN, "useWindowDimensions").mockReturnValue({
            height: 100,
            width: 400,
            scale: 1,
            fontScale: 1
        })

        const testGameState: GameState = [
            [{}, {}, {}],
            [{}, {}, {}],
            [{}, {}, {}]
        ]

        render(<Grid
            cellPressHandler={() => { }}
            gameState={testGameState}
        />);

        const sample = screen.getByLabelText("tic tac toe grid");

        expect(sample).toHaveStyle({ height: 90, width: 90 });
    });
})

the test fails because height and width is 675.

I tried to log the values of height and width in Grid.tsx and it's showing 1334 and 750

I tried to log the values of height and width by calling useWindowDimensions in Grid.test.tsx

// Grid.test.tsx

...

import { useWindowDimensions } form "react-native"

...

it("should ...", () => {

    jest.spyOn(RN, "useWindowDimensions").mockReturnValue({
            height: 100,
            width: 400,
            scale: 1,
            fontScale: 1
        })

    console.log(useWindowDimensions())
    console.log(RN.useWindowDimensions())

}

and both returned 90.

The expected behavior is that the test does not fail because useWindowDimensions is mocked and I get the correct values. But if I am missing something please let me know.

Thanks in advance...

0

There are 0 best solutions below