Bra*_*Tom 10 javascript unit-testing mocking jestjs
我有一个这样的手动模拟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
Run Code Online (Sandbox Code Playgroud)
基本上是这样测试的:
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())
})
})
...
Run Code Online (Sandbox Code Playgroud)
但是,如果在同一个测试文件中,我测试decryptCookieValue从内部调用的另一种方法crypto.createDecipheriv不再返回我的模拟解密,则此方法有效。而是返回未定义。例如:
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})
})
})
})
Run Code Online (Sandbox Code Playgroud)
我认为这是重置手动模拟的一个问题,因为如果我接受以后的测试,并使用相同的周围测试工具将其全部移动到文件中,则效果很好。
// 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})
})
})
})
Run Code Online (Sandbox Code Playgroud)
我的评估在这里是否正确?如果是,在每次测试后如何重设手动模拟的状态?
小智 4
来自 Jest 文档:执行所有操作mockFn.mockClear(),并删除任何模拟的返回值或实现。参考: https: //jestjs.io/docs/en/mock-function-api#mockfnmockreset
在您的示例中,您假设调用resetAllMocks会将您的手动模拟设置回来,但事实并非如此。
您的测试在单独的文件中工作的原因是因为 jest 独立运行每个文件,这很好,因为您只能搞砸同一文件中的规范。
在您的特定情况下,可能会起作用的东西正在调用jest.clearAllMocks()(因为这将保留实现和返回值)。
clearMocksoptions 也可在 jest 配置对象中使用(默认为 false),如果您想清除每个测试中的所有模拟,这可能会很方便。希望这对您或遇到类似问题的其他人有所帮助。
额外提示(没有完全相关)如果您正在模拟一个正在由其他模块内部使用的模块,并且在某些特定测试中您想使用不同的模拟再次模拟该模块,请确保要求该模块正在使用模拟模块在该特定测试的内部再次进行,否则该模块仍将引用您在导入语句旁边指定的模拟。
| 归档时间: |
|
| 查看次数: |
4543 次 |
| 最近记录: |