Javascript 在jest中监视模块函数

Javascript 在jest中监视模块函数,javascript,unit-testing,lodash,jestjs,es6-modules,Javascript,Unit Testing,Lodash,Jestjs,Es6 Modules,我正在用jest编写测试,其中我想监视一些lodash函数,这些函数是我在模块中单独导入的(而不是将整个lodash模块导入为。),例如 shuffleVert函数洗牌矩阵的所有行,或仅洗牌指定列的行。因为很难用随机输出测试函数,据我所知,我只想测试lodash的shuffle和pick函数是否在测试函数中被调用 我目前已经在我的测试模块中实现了一个工作间谍程序,但我不认为它是传统的或有效的,我只是认为必须有更好的方法来实现这一点 /* matrix.test.js */ import {

我正在用jest编写测试,其中我想监视一些lodash函数,这些函数是我在模块中单独导入的(而不是将整个lodash模块导入为
),例如

shuffleVert
函数洗牌矩阵的所有行,或仅洗牌指定列的行。因为很难用随机输出测试函数,据我所知,我只想测试lodash的shuffle和pick函数是否在测试函数中被调用

我目前已经在我的测试模块中实现了一个工作间谍程序,但我不认为它是传统的或有效的,我只是认为必须有更好的方法来实现这一点

/* matrix.test.js */
import {
  shuffleVert,
} from 'matrix'

/** Generate a mock functions to spy on lodash */
const mockShuffle = jest.fn()
jest.mock('lodash/shuffle', () => a => {
  const shuffle = jest.requireActual('lodash/shuffle')
  mockShuffle()
  return shuffle(a)
})

const mockPick = jest.fn()
jest.mock('lodash/pick', () => (a, b) => {
  const pick = jest.requireActual('lodash/pick')
  mockPick()
  return pick(a, b)
})

describe('reverseRows', () => {
  let srcMatrix
  beforeEach(() => {
    srcMatrix = [
      { number: 1, word: 'one' },
      { number: 2, word: 'two' },
      { number: 3, word: 'three' }
    ]
    mockShuffle.mockClear()
    mockPick.mockClear()
  })

  it('should shuffle the rows of the entire matrix with no argument for columns', () => {
    shuffleVert(srcMatrix)
    // 2 is weird, but seems correct.
    // It appears the shuffle function calls itself recursively
    expect(mockShuffle).toHaveBeenCalledTimes(2)
  })

  it('should only shuffle the rows of columns that were specified', () => {
    shuffleVert(srcMatrix, ['word'])
    expect(mockShuffle).toHaveBeenCalledTimes(2)
    expect(mockPick).toHaveBeenCalledTimes(2)
  })
})
我知道jest有一个
spyOn
功能,但这似乎只适用于对象方法,因此

import * as lodash from 'lodash'
const shuffleSpy = jest.spyOn(lodash, 'shuffle')
导致错误
无法在原语值上进行间谍;未定义的给定值


通常,监视模块方法的最佳方式是什么?是否有更好的实现方法来实现我想要实现的目标?或者这已经是一条路了?

请尝试一下,并告诉我它是否适合您

import { shuffleVert } from 'matrix';
const shuffleVertRef = {
    shuffleVert
};
let spyShuffleVert;

beforeEach(() => {
    spyShuffleVert = jest.spyOn(shuffleVertRef, "shuffleVert");
}

afterEach(() => {
    jest.clearAllMocks();
}

it('should shuffle the rows of the entire matrix with no argument for columns', () = {
    let srcMatrix = [
        { number: 1, word: 'one' },
        { number: 2, word: 'two' },
        { number: 3, word: 'three' }
    ];

    shuffleVert(srcMatrix);
    expect(spyShuffleVert).toHaveBeenCalledTimes(2);
}
然后,如果您想检查任何其他函数的执行时间,只需将它们添加到该常数中,并在下面添加它们


我也不完全理解这一点,但从我读到的一点来看,最新版本的JavaScript有一个称为“单一真实源”的原则,这是某些事情正常运行所必需的。

包.json
中指定的
洛达斯
?看起来
lodash
jest.spyOn(lodash,'shuffle')
中未定义。是的,lodash存在并在整个应用程序中使用。您解决过这个问题吗?我现在也在努力解决同样的问题。这是很久以前的事了,所以我真的不记得我是如何解决这个问题的。我想我采取了一种完全不同于使用玩笑间谍的方法…谢谢你的建议。我很久以前问过这个问题,我想我采取了一种完全不同的方法来解决这个问题,所以我没有现成的代码来尝试你的建议。如果我再次遇到同样的情况(毫无疑问),我会尝试!
import { shuffleVert } from 'matrix';
const shuffleVertRef = {
    shuffleVert
};
let spyShuffleVert;

beforeEach(() => {
    spyShuffleVert = jest.spyOn(shuffleVertRef, "shuffleVert");
}

afterEach(() => {
    jest.clearAllMocks();
}

it('should shuffle the rows of the entire matrix with no argument for columns', () = {
    let srcMatrix = [
        { number: 1, word: 'one' },
        { number: 2, word: 'two' },
        { number: 3, word: 'three' }
    ];

    shuffleVert(srcMatrix);
    expect(spyShuffleVert).toHaveBeenCalledTimes(2);
}