NodeJS: Как мне выполнить модульное тестирование функции Async, которая зависит от других вызовов Async - PullRequest
0 голосов
/ 16 мая 2018

У меня есть сервис, в который я внедряю модель Мангуста, и затем этот сервис используется моими экспресс-маршрутами для выполнения определенных функций. Я был озадачен тем, как выполнить модульное тестирование приведенного ниже кода, поскольку существует несколько асинхронных вызовов для извлечения данных из БД для выполнения некоторых вычислений, а затем для возврата результата.

Я новичок в асинхронном модульном тестировании и использую Jest Runner с Sinon.

// Service.ts
export default class Service {
    constructor(private dbModel){}

    public async problemFunc(arg1, arg2, arg3) {
        // validate args
        let data1;
        let data2;
        let data3;
        try {
            data1 = await SomeOtherService1.getData();
        }
        catch(e) {
            return e;
        }
        try {
            data2 = await SomeOtherService2.getData();
        }
        catch(e) {
            return e;
        }

        try {
            data3 = await this.dbModel
                    .findById(arg1)
                    .where('some_field')
                    .exists(false);
        }
        catch(e) {
            return e;
        }

        const calcResult = CalculationService.calc(arg1, data1, data2, data3);

        if (calcResult) {
            await this.dbModel.findByIdAndUpdate(arg1, calcResult);
            return this.dbModel.findById(arg1);
        } else {
            return new Error('Fail');
        }
    }
}

Было бы очень полезно, если бы кто-то мог объяснить, как выполнить модульное тестирование такой сложной (на мой взгляд, сложной) функции.

1 Ответ

0 голосов
/ 16 мая 2018

Синтаксические проблемы

Если это только синтаксическая проблема, вы можете использовать mocha следующим образом:

describe('my test suite', () => {

    it('should return valid data', async () => {
         let service = new Service();
         let res = await service.problemFunc({...});
         expect(res).to.equal(...);
    });
});

Если вы ожидаете, что ваш problemFunc выдаст ошибку, вы должны использовать npmmodule chaiAsPromised, потому что это асинхронная функция (возвращает обещание).


Спецификации внешних зависимостей

Здесь вы видите несколько внешних зависимостей с бизнес-логикой, смешанной вместе.Для проверки таких внешних зависимостей вы должны использовать внедрение зависимостей.

Вы передаете внешние зависимости через конструктор вашего класса Service.

constructor(private externalService1, private externalService2){
    this.externalService1 = externalService1;
    this.externalService2 = externalService2;
}

Тогда ваш метод должен выглядеть следующим образом:

async problemFunc() {
    let data1 = await this.externalService1.getData();
    let data2 = await this.externalService2.getData();
}

Поэтому вы можете смоделировать внешние зависимости в вашем наборе тестов:

describe('my test suite', () => {

    it('should return valid data', async () => {
         let fakeDb1 = {
             getData: () => { return {}; }
         }

         let fakeDb2 = {
             getData: () => { return {}; }
         }
         let service = new Service(fakeDb1, fakeDb2);
         let res = await service.problemFunc({...});
         expect(res).to.equal(...);
    });
});

Этот список хорошо написанных статей может быть полезен: https://enterprisecraftsmanship.com/2015/06/29/test-induced-design-damage-or-why-tdd-is-so-painful/

...