Тестирование кода с универсальным уловом с помощью Jest - условие гонки - PullRequest
0 голосов
/ 29 ноября 2018

Я только что понял, что у всего моего тестового кода есть условие гонки.

Мой шаблон стиля выглядит примерно так:

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

Я тестирую с Jest.Тестовый код выглядит примерно так:

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

    myFunc(callback);
});

У меня есть десятки функций и тестов, следующих этому шаблону.Последний тест, который я написал, дал мне ошибку соответствия Jest в моем обратном вызове.После многих недоразумений я понял, что первое выполнение обратного вызова вызывает сбой Jest, и выполняется обратный вызов с параметром err, и происходит сбой перед вызовом done () при первом выполнении обратного вызова.

I'mПонимание этого паттерна может быть абсолютно ужасным.Мне удалось преодолеть состояние гонки, выполнив определенные вызовы wait () в определенном порядке, но это никак не получается.

Как я могу убрать здесь потенциальное состояние гонки?

Я готов полностью изменить стиль. Я делаю это.Я знаю, что мой Javascript не особенно хорош, и система все еще находится на ранней стадии разработки.

1 Ответ

0 голосов
/ 29 ноября 2018

Мой коллега сообщил мне, что это хороший случай, чтобы использовать async / await.

См. Новую версию тестируемого кода:

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);
    });
};

Я немного обновил содержимое, чтобызаставить его казаться более реалистичным.

Я знаю, что это заставляет myFunc возвращать обещание, но это нормально для моего варианта использования.Делая это, я гарантирую, что обратный вызов выполняется только один раз, предотвращая распространение ошибки Jest в другом месте.

РЕДАКТИРОВАТЬ: я понимаю, что это то же самое, как если бы я переместил catch блок должен быть перед последним then блоком, у меня будет такое же поведение: /

...