如何用玩笑取消模拟单个实例方法

bre*_*ter 16 mocking ecmascript-6 jestjs es6-class

来自 rspec,我无法理解开玩笑的嘲弄。我正在尝试的方法是自动模拟一个类的构造函数及其所有函数,然后将它们一个一个地取消模拟以仅测试该函数。我能找到的唯一文档是使用 2 个类,模拟 1 个类,然后测试这些函数是否是从另一个未模拟的类调用的。

下面是我正在尝试做的一个基本的、人为的想法。有人可以指导我以开玩笑的方式这样做吗?

foo.js

class Foo
  constructor: ->
    this.bar()
    this.baz()
  bar: ->
    return 'bar'
  baz: ->
    return 'baz'
Run Code Online (Sandbox Code Playgroud)

foo_test.js

// require the class
Foo = require('foo')

// mock entire Foo class methods
jest.mock('foo')

// unmock just the bar method
jest.unmock(Foo::bar)

// or by
Foo::bar.mockRestore()

// and should now be able to call
foo = new Foo
foo.bar() // 'bar'
foo.baz() // undefined (still mocked)

// i even tried unmocking the instance
foo = new Foo
jest.unmock(foo.bar)
foo.bar.mockRestore()
Run Code Online (Sandbox Code Playgroud)

Nic*_*bal 10

mockFn.mockRestore()为我工作jest@24.9.0

// Create a spy with a mock
const consoleInfoSpy = jest.spyOn(console, 'info').mockImplementation(() => {})

// Run test or whatever code which uses console.info
console.info('This bypasses the real console.info')

// Restore original console.info
consoleInfoSpy.mockRestore()
Run Code Online (Sandbox Code Playgroud)


And*_*rle 5

在 Jest 中模拟它后无法获得原始模块。什么jest.mock是用你的模拟替换模块。

所以即使你写:

Foo = require('foo')
jest.mock('foo')
Run Code Online (Sandbox Code Playgroud)

Jest 会将jest.mock('foo')调用提升到调用堆栈的顶部,因此这是测试开始时发生的第一件事。这也会影响您导入的所有其他模块和 import foo.js

您可以尝试使用spyOnspy 对象的函数,也应该使用类,但我不太确定。


ree*_*rej 5

这并不严格适用于 OP,但寻求答案的人可能会在这里结束。对于所有测试,您可以模拟除某些部分之外的模块。

嘲笑/saladMaker.js

// Let Jest create the mock.
const saladMaker = jest.genMockFromModule('../saladMaker');

// Get the unmocked chop method.
const {chop} = require.requireActual('../saladMaker');

// Patch it in.
saladMaker.chop = chop;

module.exports = saladMaker;

Run Code Online (Sandbox Code Playgroud)

关键部分是用来requireActual获取未模拟的模块。

绕过模块模拟

更新

require.requireActual 已替换jest.requireActual