Jest spyOn函数不是Class或Object类型

时间:2018-03-23 19:57:16

标签: javascript jasmine jestjs

我熟悉在Class或Object方法上设置间谍,但是当函数只是一个导出默认值时 - 这样方法本身是独立的,就像实用程序一样?

我有一些像这样的现有代码:

const Funct1 = props => {
  if(props){
    Funct2(args);
  }
  // or return something
};
const Funct2 = props => {
  // do something
  return true
};
export default Funct1;  //Yes the existing export is named the same as the "entry" method above.

并且,例如,我想监视Funct1被调用,Funct2返回true。

import Funct1 from "../../../src/components/Funct1";
describe("Test the Thing", () => {
    it("New Test", () => {
        let props = {
            active: true,
            agentStatus: "online"
        };
        const spy = spyOn(Funct2, "method name"); <-- how doe this work if not an obj or class?

        Funct1(props);
        //If I try Funct2(props) instead, terminal output is "Funct2 is not defined"

        expect(spy).toHaveBeenCalledWith(props);
    });
});

4 个答案:

答案 0 :(得分:0)

我不是开玩笑的专家,但是我建议考虑一下:

1)当函数默认导出时,我使用类似的东西:

import Funct1 from "../../../src/components/Funct1";
...
jest.mock("../../../src/components/Funct1");
...
expect(Funct1).toHaveBeenCalledWith(params);

2)当模块(utils.js)具有多个导出为

export const f1 = () => {};
...
export const f8 = () => {};

您可以尝试

import * as Utils from "../../../src/components/utils"
const f8Spy = jest.spyOn(Utils, 'f8');
...
expect(f8Spy).toHaveBeenCalledWith(params);

Similar discussion here

答案 1 :(得分:0)

我认为 Jest 需要在对象或类中进行模拟,但如果它们在您的代码中不是这样,您仍然可以将它们放在测试中:

jest.mock('../pathToUtils', () => ({
  func2: jest.fun().mockImplementation((props) => "ok") //return what you want
  otherfuncs: ...etc
}));

const mockUtils = require('../pathToUtils')
const func1 = require('./pathToFunc1')

然后在测试中:

func1()  // call the main function

expect(mockUtils.func2).toHaveBeenCalled
expect(mockUtils.func2).toHaveBeenCalledTimes(1)
expect(mockUtils.func2).toHaveBeenCalledWith(arg1, arg2, etc)
expect(mockUtils.func2).toHaveBeenLastCalledWith(arg1, arg2, etc)

您已经在另一个文件中对 Util 函数进行了单元测试,因此您实际上不会在这里再次运行该函数,这只是出于集成测试的目的而进行的模拟。

答案 2 :(得分:0)

jest.fn 包裹你的函数。像这样:

const simpleFn = (arg) => arg;
const simpleFnSpy = jest.fn(simpleFn);
simpleFnSpy(1);
expect(simpleFnSpy).toBeCalledWith(1); // Passes test

答案 3 :(得分:-1)

我认为无法在不修改现有代码的情况下测试Funct1调用Funct2。如果后者是一个选项,这里有两个引入依赖注入的选项:

  • 创建并导出工厂函数:

    const Funct2 = props => {
        // do something
        return true;
    };
    const Funct1 = CreateFunct1(Funct2);
    export function CreateFunct1(Funct2) {
        return props => {
            if (props) {
                Funct2(props);
            }
            // or return something
        };
    }
    export default Funct1;  
    
    // and here is the test:
    
    describe('Test the Thing', () => {
        it('New Test', () => {
            // Arrange
            const funct2Spy = jasmine.createSpy('Funct2');
            const funct1 = CreateFunct1(funct2Spy);
            const props = "some data";
    
            // Act
            funct1(props);
    
            // Assert
            expect(funct2Spy).toHaveBeenCalledWith(props);
        });
    });
    
  • 导出Funct2。这是关于此主题的thread。由于导出语法,也许它的示例必须针对您的场景进行一些调整。