Jest 间谍在函数上不是类或对象类型



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

我有一些现有的代码,如下所示:

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);
    });
});

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

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);

类似的讨论在这里

jest.fn 包装函数。喜欢这个:

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

我认为 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 函数的单元测试,因此您实际上不会在此处再次运行该函数,这只是出于集成测试目的的模拟。

我相信

在不修改现有代码的情况下不可能测试调用 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);
        });
    });
    
  • 也导出功能2。这是关于这个主题的一个线程。由于导出语法,也许它的示例必须针对您的方案进行一些调整。

最新更新