【问题标题】:Jest doesn't await Set operations?Jest 不等待 Set 操作?
【发布时间】:2018-08-15 13:22:28
【问题描述】:

我正在通过 Jest 在 Node 中编写一个测试,在该测试中我读取了一堆 CSV 文件,解析特定列,将其放入一个集合中,然后针对该集合验证一个计数器以确定是否存在重复。

但是,解析 CSV 值的操作设置起来相当冗长(3-4 分钟)。然而,Jest 不会等待:它只是立即通过测试。

示例代码:

describe('Test that all values are unique', () => {
    let validationCounter = 0
    const validationSet = new Set([])
    it('Read all csv files', () => {
        for (const number of dirsToCheck.keys()) {
            const baseDest = baseDir + "/something" + number
            Filehound.create()
            .ext('csv')
            .paths(baseDest)
            .find((err, csvFiles) => {
                if (err) {
                    return console.error("handle err", err)
                } else {
                    for (file of csvFiles) {
                        csv({
                            flatKeys: true,
                        })
                        .fromFile(file)
                        .on("json", (jsonObj) => {
                            const designatedValue = Object.values(jsonObj).toString().split(';')[2]
                            validationSet.add(designatedValue)
                            validationCounter++
                            console.log(designatedValue) // Will make everything "hang" until this is finished, if logged
                        })
                    }
                }
            });
        }
    })
    it('Validate array counter to the unique set', () =>{
        console.log(validationCounter) // Returns 0?
        console.log(validationSet.size) // Also 0?
        expect(uniqueVurderingsejendomsIds.size).toBe(validationCounter); // Somehow passes?
    })
});

如果我console.log(designatedValue),它将持续运行整整四分钟,然后在完成将它们添加到集合后退出 - 不运行测试。

如果我删除这个 console.log 语句,Jest 将几乎立即(2 秒)通过整个测试套件

发生了什么,为什么 Jest 不等待这个操作?它立即通过了所有测试,然后 Jest 挂起而不退出。这是非常奇怪的行为。

【问题讨论】:

    标签: node.js csv jestjs


    【解决方案1】:

    它不会自动等待。

    如果您正在执行任何异步操作,您需要向您的测试发出信号等待,否则测试假定同步代码,“匆忙”通过它,没有发现错误并认为它是成功的。

    这是通过在 test 回调中指定 done 参数,然后在实际完成异步处理时调用该参数来完成的。

    来自Jest: Testing Asynchronous Code

    有一种替代形式的测试可以解决这个问题。不要将测试放在一个带空参数的函数中,而是使用一个名为 done 的参数。 Jest 会等到 done 回调被调用后才完成测试。

    describe('fetchData', () => {
      it('callback with peanut butter', done => {
        fetchData((err, result) => {
          if (err) {
            // calling `done` with an argument assumes an error
            // and fails the test
            return done(err)
          }
    
          expect(result).toBe('peanut butter')
          done()
        })
      })
    })
    
    function fetchData(cb) {
      setTimeout(() => {
        cb(null, 'peanut butter')
      }, 200)
    }
    

    在您尝试此操作之前,请确保您拥有 最新 版本的 Jest。 Jest 中有 used to be a bug 导致超时。

    【讨论】:

    • 我现在真的很确定如何实现这个:我应该使用test而不是describe吗? it 模块应该如何构建? fetchData 在您的示例中代表什么?
    • 不,您可以使用it('should do x', done => ...)。 fetchData 只是一个需要回调的异步操作。让我重新写一下更清楚。
    • 获取Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout 但我的进程不是真的异步?所以我不明白这种方法是如何工作的。
    • 您使用的是旧版本的 Jest。再次运行$ npm uninstall -g jest$ npm install -g jest。在旧版本的 Jest 中有一个 bug/strange behaviour
    • 没有变化。 jest --version >> v22.4.2。仍然收到超时错误。
    猜你喜欢
    • 2015-02-02
    • 2021-04-01
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-22
    • 2019-09-24
    相关资源
    最近更新 更多