gpt4 book ai didi

javascript - 如何在 Jest 中重置手动模拟

转载 作者:数据小太阳 更新时间:2023-10-29 03:58:02 25 4
gpt4 key购买 nike

我有一个 crypto 的手动模拟,如下所示:

// __mocks__/crypto.js

const crypto = jest.genMockFromModule('crypto')
const toString: Function = jest.fn(() => {
return {}.toString()
})
const mockStringable = {toString}
const update: Function = jest.fn(() => mockStringable)
const deciper = {update}
crypto.createDecipheriv = jest.fn(() => deciper)

export default crypto

基本上是这样测试的:

const crypto = require('crypto')
jest.mock('crypto')

describe('cookie-parser', () => {
afterEach(() => {
jest.resetAllMocks()
})
describe('decryptCookieValue', () => {
it('should call the crypto library correctly', () => {
const result = decryptCookieValue('test-encryption-key', 'test-encrypted-value')
expect(crypto.pbkdf2Sync).toHaveBeenCalledTimes(2)
expect(crypto.createDecipheriv).toHaveBeenCalled()
// more tests, etc, etc, etc
expect(crypto.createDecipheriv('', '', '').update).toHaveBeenCalled()
expect(result).toEqual({}.toString())
})
})

...

但是,如果在同一个测试文件中,我测试了另一个从 crypto.createDecipheriv 中调用 decryptCookieValue 的方法,则此方法不再返回我的模拟解密。相反,它返回未定义。例如:

describe('cookie-parser', () => {
afterEach(() => {
jest.resetAllMocks()
})
describe('decryptCookieValue', () => {
it('should call the crypto library correctly', () => {
const result = decryptCookieValue('test-encryption-key', 'test-encrypted-value')
expect(crypto.pbkdf2Sync).toHaveBeenCalledTimes(2)
expect(crypto.createDecipheriv).toHaveBeenCalled()
expect(crypto.createDecipheriv('', '', '').update).toHaveBeenCalled()
expect(result).toEqual({}.toString())
})
})
...
...
describe('parseAuthenticationCookie', () => {
it('should create the correct object', () => {

// parseAuthenticationCookie calls decryptCookieValue internally

const result = parseAuthenticationCookie('', '') // Fails because internal call to crypto.createDecipheriv stops returning mock decipher.
expect(result).toEqual({accessToken: null})
})
})
})

我认为这是重置手动模拟的一个问题,因为如果我进行稍后的测试并将其单独移动到一个文件中,并使用相同的周围测试工具,它就可以正常工作。

// new test file
import crypto from 'crypto'
import { parseAuthenticationCookie } from './index'

jest.mock('crypto')

describe('cookie-parser', () => {
afterEach(() => {
jest.resetAllMocks()
})
describe('parseAuthenticationCookie', () => {
it('should create the correct object', () => {

// Works just fine now

const result = parseAuthenticationCookie('', '')
expect(result).toEqual({accessToken: null})
})
})
})

我的评估是否正确?如果正确,我该如何在每次测试后重置手动模拟的状态?

最佳答案

来自 Jest 文档:执行 mockFn.mockClear() 执行的所有操作,并删除任何模拟的返回值或实现。引用:https://jestjs.io/docs/en/mock-function-api#mockfnmockreset

在您的示例中,您假设调用 resetAllMocks 将设置您的手动模拟,但事实并非如此。

你的测试在一个单独的文件中工作的原因是因为 jest 运行每个独立的文件,这很好,因为你只能搞砸同一文件中的规范。

在您的特定情况下,调用 jest.clearAllMocks() 可能会起作用(因为这将保留实现和返回值)。clearMocks 选项在 jest 配置对象中也可用(默认为 false),如果你想在每次测试中清除所有模拟,这可能很方便。希望这对您或其他遇到类似问题的人有所帮助。

奖金提示(没有完全相关)如果您正在模拟一个模块,它正在被其他模块内部使用,并且在某些特定测试中您想要使用不同的模拟再次模拟该模块,请确保要求模块在该特定测试中再次在内部使用模拟模块,否则该模块仍将引用您在导入语句旁边指定的模拟。

关于javascript - 如何在 Jest 中重置手动模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49494744/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com