Jestjs如何测试在另一个函数内部调用的函数
Jestjs how to test function being called inside another function
为了测试,我使用了 jest 和 react-test-renderer。它应该很容易测试,但是我很难找到合适的例子。我曾尝试做类似的事情(通常我将函数保存在单独的文件中):
utils.js
export const childFunction = () => 'something';
const parentFunction = () => childFunction();
export default parentFunction;
utils.test.js
import parentFunction from './utils.js';
it('childFunction should be called', () => {
const childFunction = jest.fn();
parentFunction();
expect(childFunction).toBeCalled();
})
片段 const childFunction = jest.fn(); 肯定不行。在调用时,parentFunction 的主体只关心它自己的范围。但如果我导入 childFunction 并执行 jest.mock(childFunction),它也不会工作,因为 jest.mock 需要一个字符串,一个 url 到一个模块,而不是函数本身。
上面的示例不起作用,我正在寻找替代方法。然而,这在使用 ShallowRenderer 渲染组件后有效。我想通过嵌套在另一个函数中的函数实现类似的行为。
class Component extends React.Component {
componentDidMount() {parentFunction()}
render() {...}
}
const renderer = new ShallowRenderer();
describe("testing parentFunction", () => {
renderer.render(<Component/>);
it("parentFunction should be called", () => {
expect(parentFunction).toBeCalled();
});
});
不确定这是否有帮助,但它可能会给您一些想法。
首先,上面的例子:
// this needs to be stubbed
// const childFunction = () => 'something';
const childFunction = jest.fn();
const parentFunction = () => childFunction();
it('childFunction should be called', () => {
parentFunction();
expect(childFunction).toHaveBeenCalled();
}
这是一个有点人为的例子,因为 childFunction
不太可能被导出,所以您无法获得对它和 mock/stub 的引用。
您的一个解决方法是将其移出到自己的方法中
class Component extends React.Component {
componentDidMount() {
this.parentFunction();
}
parentFunction() {
parentFunction(); // from elsewhere
}
render() {...}
}
这允许您创建穿孔并监视组件原型。
例如
const spy = jest.spyOn(Component.prototype, 'parentFunction');
// ... mount so lifecycle runs...
expect(spy).toHaveBeenCalled(); // and clear the spy mocks after!
模拟模块可能更好
例如,您的组件使用 utils.js 执行以下操作:
export function parentFunction(){ console.log('parent'); }
component.js 是:
import { parentFunction } from './utils';
你可以在测试中做:
const utils = require('./utils');
utils.parentFunction = jest.fn();
import Component from './component';
// later
expect(utils.parentFunction).toHaveBeenCalled();
如您所见,有许多可能的方法,虽然我不确定该测试的价值,但您应该测试组件的输出/功能,而不是它调用的,有一些东西 运行 on componentDidMount
是给定的,只有在有人转换为函数式或更改生命周期名称时才会中断。
如果函数未作为对象方法调用,则无法监视函数调用。
如 中所述,由于 ES 模块的工作方式,只有当函数从一个模块导出并在另一个模块中使用时,才有可能监视或模拟该函数。这样它就可以被监视到模块 *
对象,或者被 jest.mock
.
模拟
如果不是这种情况,应该间接测试:
expect(childFunction()).toBe('something');
expect(parentFunction()).toBe('something');
为了测试,我使用了 jest 和 react-test-renderer。它应该很容易测试,但是我很难找到合适的例子。我曾尝试做类似的事情(通常我将函数保存在单独的文件中):
utils.js
export const childFunction = () => 'something';
const parentFunction = () => childFunction();
export default parentFunction;
utils.test.js
import parentFunction from './utils.js';
it('childFunction should be called', () => {
const childFunction = jest.fn();
parentFunction();
expect(childFunction).toBeCalled();
})
片段 const childFunction = jest.fn(); 肯定不行。在调用时,parentFunction 的主体只关心它自己的范围。但如果我导入 childFunction 并执行 jest.mock(childFunction),它也不会工作,因为 jest.mock 需要一个字符串,一个 url 到一个模块,而不是函数本身。
上面的示例不起作用,我正在寻找替代方法。然而,这在使用 ShallowRenderer 渲染组件后有效。我想通过嵌套在另一个函数中的函数实现类似的行为。
class Component extends React.Component {
componentDidMount() {parentFunction()}
render() {...}
}
const renderer = new ShallowRenderer();
describe("testing parentFunction", () => {
renderer.render(<Component/>);
it("parentFunction should be called", () => {
expect(parentFunction).toBeCalled();
});
});
不确定这是否有帮助,但它可能会给您一些想法。
首先,上面的例子:
// this needs to be stubbed
// const childFunction = () => 'something';
const childFunction = jest.fn();
const parentFunction = () => childFunction();
it('childFunction should be called', () => {
parentFunction();
expect(childFunction).toHaveBeenCalled();
}
这是一个有点人为的例子,因为 childFunction
不太可能被导出,所以您无法获得对它和 mock/stub 的引用。
您的一个解决方法是将其移出到自己的方法中
class Component extends React.Component {
componentDidMount() {
this.parentFunction();
}
parentFunction() {
parentFunction(); // from elsewhere
}
render() {...}
}
这允许您创建穿孔并监视组件原型。
例如
const spy = jest.spyOn(Component.prototype, 'parentFunction');
// ... mount so lifecycle runs...
expect(spy).toHaveBeenCalled(); // and clear the spy mocks after!
模拟模块可能更好
例如,您的组件使用 utils.js 执行以下操作:
export function parentFunction(){ console.log('parent'); }
component.js 是:
import { parentFunction } from './utils';
你可以在测试中做:
const utils = require('./utils');
utils.parentFunction = jest.fn();
import Component from './component';
// later
expect(utils.parentFunction).toHaveBeenCalled();
如您所见,有许多可能的方法,虽然我不确定该测试的价值,但您应该测试组件的输出/功能,而不是它调用的,有一些东西 运行 on componentDidMount
是给定的,只有在有人转换为函数式或更改生命周期名称时才会中断。
如果函数未作为对象方法调用,则无法监视函数调用。
如 *
对象,或者被 jest.mock
.
如果不是这种情况,应该间接测试:
expect(childFunction()).toBe('something');
expect(parentFunction()).toBe('something');