Jest로 단위 테스트 맵 기능

Jest로 지도 기능을 단위 테스트할 때 문제가 발생했습니다. 배열 맵에 함수에 대한 참조만 주었더니 결과적으로 문제가 생겼습니다. 그 일이 일어난 방법은 다음과 같습니다.

import { functionInsideMap } from './functionInsideMap';

export function referenceToArrowFuncInMap(names: string[]): string[] {
    const namesWithHello = names.map(functionInsideMap);
    return namesWithHello;
}


위의 referenceToArrowFuncInMap은 각 배열 값에 functionInsideMap을 적용합니다. referenceToArrowFuncInMap에 대한 단위 테스트를 작성해 봅시다.

import { referenceToArrowFuncInMap } from './index';
import { functionInsideMap } from './functionInsideMap';

jest.mock('./functionInsideMap');
const mockedFunctionInsideMap = jest.mocked(functionInsideMap, false);

describe("Test the 'referenceToArrowFuncInMap' function", () => {
    beforeEach(() => {
        mockedFunctionInsideMap.mockReset();
    });

    it('Using reference to function inside map will fail', () => {
        //Arrange
        //Setting inputs
        const names = ['John', 'Matt'];

        //Setting output
        const expectedOutput = ['Hello John!', 'Hello Matt!'];

        //Mocking functions and objects
        mockedFunctionInsideMap
            .mockReturnValueOnce('Hello John!')
            .mockReturnValueOnce('Hello Matt!');

        //Act
        const callOutput = referenceToArrowFuncInMap(names);

        //Assert output
        expect(callOutput).toEqual(expectedOutput);

        //Assert function under test internals
        expect(functionInsideMap).toHaveBeenCalledTimes(2);
        expect(functionInsideMap).toHaveBeenNthCalledWith(1, 'John');
        expect(functionInsideMap).toHaveBeenNthCalledWith(2, 'Matt');
    });
});


위의 단위 테스트를 실행할 때 Jest에서 다음 오류가 발생합니다. functionInsideMap에 대한 toHaveBeenNthCalledWith 어설션이 중단되는 것 같습니다.

> [email protected] test
> jest

 FAIL  src/index.referenceToArrowFuncInMap.spec.ts
  Test the 'referenceToArrowFuncInMap' function
    ✕ Using reference to function inside map will fail (11 ms)

  ● Test the 'referenceToArrowFuncInMap' function › Using reference to function inside map will fail

    expect(jest.fn()).toHaveBeenNthCalledWith(n, ...expected)

    n: 1
    Expected: "John"
    Received
    ->     1: "John", 0, ["John", "Matt"]
           2: "Matt", 1, ["John", "Matt"]

    Number of calls: 2

      31 |              //Assert function under test internals
      32 |              expect(functionInsideMap).toHaveBeenCalledTimes(2);
    > 33 |              expect(functionInsideMap).toHaveBeenNthCalledWith(1, 'John');
         |                                        ^
      34 |              expect(functionInsideMap).toHaveBeenNthCalledWith(2, 'Matt');
      35 |      });
      36 | });

      at Object.<anonymous> (src/index.referenceToArrowFuncInMap.spec.ts:33:29)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.79 s
Ran all test suites.


Jest는 functionInsideMap이 "John"값으로 호출될 것으로 예상했습니다. 그러나 대신 맵은 3개의 값으로 호출했습니다.
  • "존"
  • 0
  • ["존", "매트"]

  • 이유



    Javascript 배열 맵calls your callback-function with three arguments 때문입니다.

    1. element - The current element being processed in the array.
    2. index - The index of the current element being processed in the array.
    3. array - the array map was called upon. MDN Web Docs


    배열 맵 함수에 대한 함수 참조를 제공하면 Jest는 주어진 모든 인수를 기록합니다. 결과적으로 오류는 3개의 인수가 있는 functionInsideMap이라는 맵을 보여줍니다. 1이 아닙니다.

    이 문제를 해결하는 가장 쉬운 방법은 소스 코드를 변경하는 것입니다. 먼저 익명 함수를 지도의 콜백으로 사용합니다. 두 번째로 익명 함수 내에서 functionInsideMap을 호출합니다.

    수정




    import { functionInsideMap } from './functionInsideMap';
    
    export function referenceToArrowFuncInMap(names: string[]): string[] {
        const namesWithHello = names.map((name) => functionInsideMap(name));
        return namesWithHello;
    }
    


    이 방법으로 익명 함수는 주어진 첫 번째 인수만 사용하고 Jest는 올바른 방식으로 작동합니다.

    결론



    결론적으로 콜백 함수는 간결한 함수를 사용하는 것이 좋습니다. 먼저 이것은 단위 테스트를 더 쉽게 만듭니다. 또한 코드의 가독성도 향상됩니다. 독자는 어레이 맵이 콜백에 전달하는 내용을 명확하게 볼 수 있습니다. 간결한 기능을 갖춘 단위 테스트 맵 기능은 삶을 더 쉽게 만듭니다.

    좋은 웹페이지 즐겨찾기