javascript Jestjs如何测试在另一个函数中被调用的函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/52650367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Jestjs how to test function being called inside another function
提问by Dune
For testing I use jest and react-test-renderer. It should be simple to test, however I have a hard time finding the proper example. I have tried to do something like that (in general I keep the functions in separate files):
为了测试,我使用 jest 和 react-test-renderer。测试应该很简单,但是我很难找到合适的例子。我曾尝试做类似的事情(通常我将函数保存在单独的文件中):
utils.js
实用程序.js
export const childFunction = () => 'something';
const parentFunction = () => childFunction();
export default parentFunction;
utils.test.js
utils.test.js
import parentFunction from './utils.js';
it('childFunction should be called', () => {
const childFunction = jest.fn();
parentFunction();
expect(childFunction).toBeCalled();
})
The fragment const childFunction = jest.fn();definitely won't work. While calling, parentFunction's body cares only about its own scope. But it also won't work if I import childFunction and do jest.mock(childFunction), because jest.mock needs a string, a url to a module, and not the function itself.
片段const childFunction = jest.fn(); 肯定行不通。在调用时,parentFunction 的主体只关心它自己的作用域。但是,如果我导入 childFunction 并执行jest.mock(childFunction),它也将不起作用,因为 jest.mock 需要一个字符串、一个模块的 url,而不是函数本身。
The example above doesn't work and I'm searching for an alternative. However this works after rendering the component with ShallowRenderer. And I'd like to achieve a similar behaviour with a function nested inside another function.
上面的示例不起作用,我正在寻找替代方法。然而,这在使用 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();
});
});
采纳答案by Estus Flask
There's no way to spy on function call if a function isn't called as object method.
如果函数不是作为对象方法调用的,则无法监视函数调用。
As explained in this answer, due to how ES modules work, it's possible to spy or mock a function only if it was exported from a module and is used in another module. This way it can be spied on module *object, or be mocked with jest.mock.
正如在这个答案中所解释的,由于 ES 模块的工作方式,只有当一个函数从一个模块导出并在另一个模块中使用时,才有可能监视或模拟一个函数。通过这种方式,它可以在模块*对象上被监视,或者被jest.mock.
If this isn't the case, it should be tested indirectly:
如果不是这种情况,则应进行间接测试:
expect(childFunction()).toBe('something');
expect(parentFunction()).toBe('something');
回答by Dimitar Christoff
not sure if this will help but it may give you ideas.
不确定这是否会有所帮助,但它可能会给您一些想法。
first, the example above:
首先,上面的例子:
// this needs to be stubbed
// const childFunction = () => 'something';
const childFunction = jest.fn();
const parentFunction = () => childFunction();
it('childFunction should be called', () => {
parentFunction();
expect(childFunction).toHaveBeenCalled();
}
this is a somewhat contrived example as it's unlikely that childFunctionis exported so you cannot get a reference to it and mock/stub it.
这是一个有点人为的示例,因为它不太可能childFunction被导出,因此您无法获得对它的引用并模拟/存根它。
one workaround you have would be to move it out into its own method
您拥有的一种解决方法是将其移到自己的方法中
class Component extends React.Component {
componentDidMount() {
this.parentFunction();
}
parentFunction() {
parentFunction(); // from elsewhere
}
render() {...}
}
This allows you to create a puncture and spy on the Component proto.
这允许您在组件原型上创建穿刺和监视。
eg
例如
const spy = jest.spyOn(Component.prototype, 'parentFunction');
// ... mount so lifecycle runs...
expect(spy).toHaveBeenCalled(); // and clear the spy mocks after!
it may be better to mock the module
模拟模块可能会更好
eg you have utils.js used by your component that does:
例如,您的组件使用的 utils.js 执行以下操作:
export function parentFunction(){ console.log('parent'); }
component.js does:
component.js 执行以下操作:
import { parentFunction } from './utils';
you could in your tests do:
你可以在你的测试中做:
const utils = require('./utils');
utils.parentFunction = jest.fn();
import Component from './component';
// later
expect(utils.parentFunction).toHaveBeenCalled();
as you can see, many possible ways to go, though I am not sure on the value of that test, you should probably test the output / functionality of the component rather than it had called, having something run on componentDidMountis a given and would only break if somebody converted to functional or changed the lifecycle name.
如您所见,有许多可能的方法,虽然我不确定该测试的价值,但您可能应该测试组件的输出/功能而不是它已经调用,运行某些东西componentDidMount是给定的,并且只会如果有人转换为功能或更改生命周期名称,则中断。

