【发布时间】:2019-01-23 01:31:54
【问题描述】:
这个问题与测试 javascript 和模拟函数有关。
假设我有一个如下所示的模块:
export function alpha(n) {
return `${n}${beta(n)}${n}`;
}
export function beta(n) {
return new Array(n).fill(0).map(() => ".").join("");
}
那我就不能用下面的方法测试了:
import * as indexModule from "./index";
//Not what we want to do, because we want to mock the functionality of beta
describe("alpha, large test", () => {
it("alpha(1) returns '1.1'", () => {
expect(indexModule.alpha(1)).toEqual("1.1"); //PASS
});
it("alpha(3) returns '3...3'", () => {
expect(indexModule.alpha(3)).toEqual("3...3"); //PASS
});
});
//Simple atomic test
describe("beta", () => {
it("beta(3) returns '...'", () => {
expect(indexModule.beta(3)).toEqual("..."); //FAIL: received: 'x'
});
});
//Here we are trying to mutate the beta function to mock its functionality
describe("alpha", () => {
indexModule.beta = (n) => "x";
it("works", () => {
expect(indexModule.alpha(3)).toEqual("3x3"); //FAIL, recieved: '3...3'
});
});
但是,如果将模块一分为二:
alpha.js
import { beta } from "./beta";
export function alpha(n) {
return `${n}${beta(n)}${n}`;
}
beta.js
export function beta(n) {
return new Array(n).fill(0).map(() => ".").join("");
}
然后我可以变异 beta 模块,alpha 知道它:
import { alpha } from "./alpha";
import * as betaModule from "./beta";
describe("alpha", () => {
betaModule.beta = (n) => "x";
it("works", () => {
expect(alpha(3)).toEqual("3x3"); //PASS
});
});
为什么会这样?我正在寻找技术上特定的答案。
我有一个带有此代码 here 的 Github 分支,请参阅 mutateModule 和 singleFunctionPerModuleAndMutate 文件夹。
作为一个附加问题 - 在这个例子中,我通过直接重新分配属性来改变模块。我是否正确理解使用 jest mock 功能本质上会做同样的事情?
即。如果第一个示例不起作用但第二个示例不起作用的原因是由于突变,那么它必然意味着使用 jest 模块模拟函数同样不起作用。
据我所知,在测试模块as this jest github issues talks about 时,无法模拟模块中的单个函数。我想知道 - 为什么会这样。
【问题讨论】:
-
这根本不是 Jest Mocks 的工作方式。文档非常清楚自动模拟和手动模拟的工作原理。
-
@RandyCasburn 我在问一个问题,为什么在一种情况下保留对函数的引用,而不是在另一种情况下,作为了解使用 jest 模拟时它是如何工作的起点。
-
将您的导入从
*更改为{ alpha, beta }。
标签: javascript jestjs es6-modules