내부 모듈을 호출한 함수를 조롱하는 방법

문제



Iets는 당신이 파일을 가지고 있다고 말합니다

// file.js

export function b() {
    return 'B'
}

export function a() {
    return b()
}

module.exports = {
    a,
    b,
}


함수 a가 내부적으로 함수 b를 호출하고 있습니다. 함수 b를 조롱하는 것은 매우 어려울 수 있습니다.

당신은 아마 당신의 테스트에서 이와 같은 것을 할 것입니다

jest.mock 방법 사용




jest.mock('./file', () => {
    const original = jest.requireActual('./file')
    return {
        ...orignial,
        b: jest.fn()
    }
})

const f = require('./file')

test('a', () => {
    f.b.mockReturnValue('C')

    expect(f.a()).toBe('C')
    // this will failed, it got 'B'
})


jest.spyOn 메서드 사용




const f = require('./file')

test('a', () => {
    jest.spyOn(f, 'b').mockReturnValue('C')

    expect(f.a()).toBe('C')
    // it sill failed!, it got 'B'
})


이것은 버그가 아니며 위의 두 가지 방법이 잘 작동합니다. 주된 이유는 기준점 때문입니다. 기능이 조롱되고 인쇄되면 다음과 같은 것을 볼 수 있습니다.

[Function: b] {
    _isMockFunction: true,
    getMockImplementation: [Function (anonymous)],
    mock: [Getter/Setter],
    mockClear: [Function (anonymous)],
    mockReset: [Function (anonymous)],
    mockRestore: [Function (anonymous)],    
    ...
    ...
}


이제 함수 a를 호출한 함수 b를 출력해 봅니다. 그리고 테스트를 다시 실행합니다.

export function a() {
    console.log(b) // it will print [Function: b] (without the mock property)
    return b()
}


솔루션 1



함수 b를 다른 파일로 이동합니다.

// b.js
export function b() {
    return 'B'
}



// file.js
import {b} from "./b"

export function a() {
    return b()
}


이 경우 mock b만 하면 됩니다. 저보다 더 잘 아시리라 믿습니다.

솔루션 2



동일한 기준점을 사용합니다. 이것은 당신의 코드베이스에 조금 추악할 수 있습니다. 저는 괜찮다고 생각합니다.

// file.js

export function b() {
    return 'B'
}

export function a() {
    return module.exports.b() // magic here
}

module.exports = {
    a,
    b,
}


또는 이것이 모듈을 정의하는 방식이라면 다음과 같이 할 수 있습니다.

// file.js

module.exports = {
    b: () => {
        return 'B'
    },
    a: () => {
        return this.b() // this magic
    }
}


둘 다 동일한 결과와 동일한 원리를 달성합니다.

좋은 웹페이지 즐겨찾기