每次测试的Jest Mock模块

Kan*_*tic 25 unit-testing mocking jestjs react-native

我对在Jest中嘲笑如何对实现进行单元测试感到困惑.问题是我想模仿不同的预期行为.

有没有办法实现这个目标?因为导入只能在文件的顶部,并且能够模拟在导入之前必须声明的内容.我也尝试传递一个本地函数,所以我可以覆盖行为,但是jest抱怨你不允许传递任何本地函数.

jest.mock('the-package-to-mock', () => ({
  methodToMock: jest.fn(() => console.log('Hello'))
}));

import * as theThingToTest from '../../../app/actions/toTest'
import * as types from '../../../app/actions/types'

it('test1', () => {
  expect(theThingToTest.someAction().type).toBe(types.SOME_TYPE)
})

it('test2', () => {
  //the-package-to-mock.methodToMock should behave like something else
  expect(theThingToTest.someAction().type).toBe(types.SOME_TYPE)
})
Run Code Online (Sandbox Code Playgroud)

在内部你可以想象theThingToTest.someAction()使用the-package-to-mock.methodToMock

And*_*rle 56

您可以使用间谍进行模拟并导入模拟的模块.在测试中,您可以设置模拟应该如何使用mockImplementation:

jest.mock('the-package-to-mock', () => ({
  methodToMock: jest.fn()
}));
import {methodToMock} from 'the-package-to-mock'

it('test1', () => {
  methodToMock.mockImplementation(() => 'someValue')
})

it('test2', () => {
   methodToMock.mockImplementation(() => 'anotherValue')
})
Run Code Online (Sandbox Code Playgroud)

  • 当我尝试这种方法时,我得到mockImplementation()不是一个函数. (12认同)
  • 如果`methodToMock`是一个常量属性呢? (6认同)
  • 为什么需要模拟一个常量值。无论如何,只需用值替换`jest.fn()`。也不需要“导入”模块。 (2认同)
  • 仅当您忘记将“mockImplementation”分配给“jest.fn()”时,“mockImplementation”才会被定义。我刚刚测试过 (2认同)

sli*_*wp2 12

另一种方法是使用jest.doMock(moduleName,factory,options)

\n

例如

\n

the-package-to-mock.ts:

\n
export function methodToMock() {\n  return \'real type\';\n}\n
Run Code Online (Sandbox Code Playgroud)\n

toTest.ts:

\n
import { methodToMock } from \'./the-package-to-mock\';\n\nexport function someAction() {\n  return {\n    type: methodToMock(),\n  };\n}\n
Run Code Online (Sandbox Code Playgroud)\n

toTest.spec.ts:

\n
describe(\'45006254\', () => {\n  beforeEach(() => {\n    jest.resetModules();\n  });\n  it(\'test1\', () => {\n    jest.doMock(\'./the-package-to-mock\', () => ({\n      methodToMock: jest.fn(() => \'type A\'),\n    }));\n    const theThingToTest = require(\'./toTest\');\n    expect(theThingToTest.someAction().type).toBe(\'type A\');\n  });\n\n  it(\'test2\', () => {\n    jest.doMock(\'./the-package-to-mock\', () => ({\n      methodToMock: jest.fn(() => \'type B\'),\n    }));\n    const theThingToTest = require(\'./toTest\');\n    expect(theThingToTest.someAction().type).toBe(\'type B\');\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

单元测试结果:

\n
 PASS  examples/45006254/toTest.spec.ts\n  45006254\n    \xe2\x9c\x93 test1 (2016 ms)\n    \xe2\x9c\x93 test2 (1 ms)\n\n-----------|---------|----------|---------|---------|-------------------\nFile       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s \n-----------|---------|----------|---------|---------|-------------------\nAll files  |     100 |      100 |     100 |     100 |                   \n toTest.ts |     100 |      100 |     100 |     100 |                   \n-----------|---------|----------|---------|---------|-------------------\nTest Suites: 1 passed, 1 total\nTests:       2 passed, 2 total\nSnapshots:   0 total\nTime:        3.443 s\n
Run Code Online (Sandbox Code Playgroud)\n

源代码:https://github.com/mrdulin/jest-v26-codelab/tree/main/examples/45006254

\n


Tal*_*ffe 8

我使用以下模式:

'use strict'

const packageToMock = require('../path')

jest.mock('../path')
jest.mock('../../../../../../lib/dmp.db')

beforeEach(() => {
  packageToMock.methodToMock.mockReset()
})

describe('test suite', () => {
  test('test1', () => {
    packageToMock.methodToMock.mockResolvedValue('some value')
    expect(theThingToTest.someAction().type).toBe(types.SOME_TYPE)

  })
  test('test2', () => {
    packageToMock.methodToMock.mockResolvedValue('another value')
    expect(theThingToTest.someAction().type).toBe(types.OTHER_TYPE)
  })
})
Run Code Online (Sandbox Code Playgroud)

解释:

您模拟您尝试在测试套件级别使用的类,确保在每次测试之前重置模拟,并且对于每个测试,您使用 mockResolveValue 来描述返回模拟时将返回的内容


Tho*_*röm 7

spyOn对我们来说效果最好。参见之前的回答:

/sf/answers/3805339751/