gpt4 book ai didi

javascript - 测试 Javascript 函数的阻塞行为

转载 作者:行者123 更新时间:2023-11-29 18:26:27 29 4
gpt4 key购买 nike

在 Javascript 中,我有两个版本的递归函数,一个同步运行,一个使用简单的调度异步运行。给定某些输入,在这两种情况下,函数都应具有无限的执行路径。我需要为这些功能开发测试,特别是检查异步版本不会阻塞主线程的测试。

我已经有测试在非返回情况下检查这些函数的输出回调行为,我只关心测试阻塞行为。为了测试目的,我可以将函数运行的时间限制为一段较长但有限的时间。我目前正在使用 QUnit,但可以切换到另一个测试框架。

我如何测试不返回的异步函数不会阻塞?

编辑,澄清

这将是我正在使用的函数的一个简单示例:

function a()
{
console.log("invoked");
setTimeout(a, 1000);
}

a();

我在描述中故意滥用了一些线程术语,因为我觉得它们最清楚地表达了问题。不阻塞主线程,我的意思是调用函数不会阻止其他逻辑的调度和执行。我希望函数本身将在主线程上执行,但我认为函数会在计划在将来执行时一直运行。

最佳答案

单元测试基于单一职责原则和隔离(将被测对象与其依赖项分开)。

在这种情况下,你希望你的函数异步运行,但这种行为不是由你的函数完成的,是由“setTimeout”函数完成的,所以我认为你必须将你的函数与“setTimeout”隔离开来,因为它是你的依赖项不想测试,浏览器保证它会工作。

然后,由于我们相信“setTimeout”会执行异步逻辑,我们只能测试对“setTimeout”的函数调用,我们可以用另一个函数替换“window.setTimeout”,而我们必须始终在测试完成。

function replaceSetTimeout() {
var originalSetTimeout = window.setTimeout;
var callCount = 0;

window.setTimeout = function() {
callCount++;
};

window.setTimeout.restore = function() {
window.setTimeout = originalSetTimeout;
};

window.setTimeout.getCallCount = function() {
return callCount;
};
}

replaceSetTimeout();
asyncFunction();
assert(setTimeout.getCallCount() === 1);
setTimeout.restore();

我推荐你使用sinon.js因为它提供了许多工具,例如 spies谁是函数,会告诉您调用了多少次以及调用了哪些参数。

var originalSetTimeout = window.setTimeout;
window.setTimeout = sinon.spy();
asyncFunction();

// check called only once
assert(setTimeout.calledOnce);
// check the first argument was asyncFunction
assert(setTimeout.calledWith(asyncFunction));

Sinon 还提供了fake timers谁执行 setTimeout 替换但具有更多功能,例如将模拟“x”毫秒的 .tick(x) 方法,但在这种情况下,我认为它对您没有帮助。

更新回答问题编辑:

1 - 您的函数会无限执行,因此您无法在不中断其执行的情况下对其进行测试,因此您必须在某处覆盖“setTimeout”。

2 - 您希望您的函数递归执行以允许其他代码在迭代之间执行?伟大的!但请理解您的函数不能执行此操作 您的函数只能调用 setTimeout 或 setInterval,并希望此函数按预期工作。您应该测试您的函数的作用。

3 - 您想从 Javascript(沙盒环境)进行测试,而不是另一个 Javascript 代码使用并释放唯一的一个执行线程(与您用来测试的线程相同)。你真的认为这是一个简单的测试吗?

4 - 但最重要的 - 我不喜欢白盒,因为它将测试与依赖性结合在一起,如果你改变你的依赖性或它在未来的调用方式,你将不得不改变测试。 DOM 函数不存在这个问题,DOM 函数将在多年内保持相同的接口(interface),而现在,除了调用这两个函数之一,你没有其他方法可以做你想做的事,所以我不认为在这个案例“白盒测试”是个坏主意。

我告诉你这是因为我在测试 Promise 模式实现时遇到了同样的问题,而不是必须始终异步,即使 promise 已经实现,我已经使用测试引擎异步测试方式(使用回调)对其进行了测试和东西)而且一团糟,测试随机失败,测试执行速度非常慢。然后我问一位 TDD 专家,测试怎么会这么难,他回答说我没有遵循单一责任原则,因为我试图测试我的 promise 实现和 setTimeout 行为。

关于javascript - 测试 Javascript 函数的阻塞行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12641691/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com