使用Jest的异步Javascript代码测试在不应该工作的时候工作

sycxhyv7  于 2023-04-03  发布在  Jest
关注(0)|答案(2)|浏览(134)

Jest的docs提供了一个在测试异步代码时不应该做什么的反面例子。我是这样实现的:

const expect = require('expect');

function fetchData(cb) {
    setTimeout(cb('peanut butter2'), 1500);
}

test('the data is peanut butter', () => {
    function callback(data) {
        expect(data).toBe('peanut butter');
    }

    fetchData(callback);
});

我运行npx jest test.js,输出如下:

Fabians-MacBook-Pro:playground fabian$ npx jest test.js
 FAIL  ./test.js
  ✕ the data is peanut butter (6ms)

  ● the data is peanut butter

    expect(received).toBe(expected)

    Expected value to be (using Object.is):
      "peanut butter"
    Received:
      "peanut butter2"

      at callback (playground/test.js:9:22)
      at fetchData (playground/test.js:4:16)
      at Object.<anonymous>.test (playground/test.js:12:5)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        0.866s, estimated 1s
Ran all test suites matching /test.js/i.

我不明白结果。
1.为什么我没有像Jest建议的那样调用done()来测试异步代码,它仍然可以工作?我非常确定setTimeout是异步的,因为我在一个空白的测试脚本中使用console.log()语句测试了它,并且第二个语句在第一个语句之前被触发,第一个语句被封装在setTimeout函数中。
1.此外,测试在0.866s失败,当我的超时设置为1500ms时。当我的回调甚至不应该被调用时,Jest怎么会收到不正确的回调数据(花生酱2)?

lyr7nygr

lyr7nygr1#

因为您的测试看起来应该是async,但由于代码中的错误,实际上是synchronous
下面的代码看起来像是设计用来在1500ms之后调用cb方法的,* 但实际上是立即调用cb *:
setTimeout(cb('peanut butter2'), 1500);
然后将string传递给callback函数,该函数立即/同步运行expect
你可能想要的是:
setTimeout(function() { cb('peanut butter2') }, 1500);
或者,让setTimeout将arg传递给cb函数并调用它:
setTimeout(cb, 1500, 'peanut butter2')
这实际上会在1500ms之后调用cb函数,正如预期的那样。

lb3vh1jj

lb3vh1jj2#

这个密码对我很有效

const expect = require("expect");

function fetchData(cb) {
  setTimeout(function () {
    cb("peanut butter2");
  }, 1500);
}

test("the data is peanut butter", () => {
  function callback(data) {
    expect(data).toBe("peanut butter");
  }

  fetchData(callback);
});

但我得到了警告
Jest在测试运行完成后一秒钟内未退出。
'这通常意味着在您的测试中存在未停止的异步操作。请考虑使用--detectOpenHandles运行Jest来解决此问题。

相关问题