简体   繁体   English

用Jest测试通用捕获代码-竞争条件

[英]Testing code with a universal catch with Jest - race condition

I just realized all of my test code has a race condition. 我刚刚意识到我所有的测试代码都具有竞争条件。

My style pattern follows something like this: 我的样式模式如下所示:

const myFunc = (callback) => {
    return somePromise().then((result) => {
        return someOtherPromise();
    }).then((result) => {
        db.end(() => {
            callback();
        });
    }).catch((err) => {
        db.end(() => {
            callback(err);
        });
    });
};

I'm testing with Jest. 我正在与Jest测试。 Test code looks something like this. 测试代码看起来像这样。

it('should work', (done) => {
    // mock stuff
    let callback = () => {
        expect(...);
        done();
    };

    myFunc(callback);
});

I have dozens of functions and tests following this pattern. 我遵循此模式有许多功能和测试。 The last test I wrote was giving me a Jest matcher error in my callback. 我写的最后一个测试是在回调中给我一个Jest匹配器错误。 After much confusion, I realized that the first callback execution is throwing the Jest failure, and the callback with the err parameter is being executed and failing before done() is called by the first callback execution. 经过一番困惑之后,我意识到第一次回调执行将引发Jest错误,并且带有err参数的回调正在执行,并且在第一次回调执行调用done()之前失败。

I'm realizing this pattern might be absolutely terrible. 我意识到这种模式可能绝对可怕。 I've managed to beat the race condition by having certain expect() calls in certain order, but that's no way to do this. 我已经通过按一定顺序进行某些Expect()调用来克服了竞争状况,但这是没有办法的。

How can I remove the potential for the race condition here? 我如何在这里消除比赛条件的可能性?

I'm open to completely changing the style I do this. 我愿意完全改变自己的风格。 I know my Javascript isn't particularly amazing, and the system is still pretty early in its development. 我知道我的Javascript并不是特别出色,而且该系统仍处于开发初期。

My colleague advised me that this is a good case to use async/await. 我的同事告诉我,这是使用异步/等待的一个好案例。

See a new version of the code under test: 查看受测代码的新版本:

const myFunc = async (callback) => {
    let other_result;
    try {
        let result = await somePromise();
        other_result = await someOtherPromise(result);
    } catch (err) {
        db.end(() => {
            callback(err);
        });
        return;
    }
    db.end(() => {
        callback(null, other_result);
    });
};

I updated things a bit to make it seem more real-world-ish. 我做了一些更新,使它看起来更加真实。

I know this makes myFunc return a promise, but that's okay for my use-case. 我知道这使myFunc返回了一个承诺,但是对于我的用例是可以的。 By doing this, I'm ensuring that the callback is only executed once, preventing the Jest error from getting caught up elsewhere. 通过这样做,我确保回调仅执行一次,以防止Jest错误被其他地方捕获。

EDIT: I'm realizing that this is the same as if I had moved the catch block to be before the final then block, I would have the same behavior :/ 编辑:我意识到这就像我已经将catch块移到最后的then块之前一样,我将具有相同的行为:/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM