Модульное тестирование Node JS API с использованием Jest - PullRequest
0 голосов
/ 28 февраля 2020

Я пытаюсь написать примеры модульных тестов для NodeJS API, высмеивая вызов БД с помощью jest.fn(() => Promise.resolve(["FAQ 1"]));

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

const getFAQ=(request,reply)=>{

faqs.findByCondition(request.params.filter,success=>{
    reply(Response.sendResponse(true, success, ResponseMessages.SUCCESS, StatusCodes.OK));
 }, error => {
    log.error('ERROR : ', error);
         reply(Response.sendResponse(false, error, ResponseMessages.ERROR, 400));
    });

};

Моя модель JS, содержащая findByCondition(), выглядит примерно так:

findByCondition = (condition, success_callback, error_callback) => {
        "use strict";
        faq.find(condition, (err, docs) => {
            if (err) {
                error_callback(err);
            } else {
                success_callback(docs);
            }
        });
    }

Я попытался написать свой пример модульного теста следующим образом:

describe("test cases for FAQ Factory", () => {
    utils.callAPI = jest.fn(() => 'test')

    test('getFAQ Success Case', (done) => {
        const request = {
            params: {
                filter: 'all'
            },
            headers: {
                authorization: 'asfasfasdfas'
            }
        }
        faqModel.findByCondition = jest.fn(() => Promise.resolve(["FAQ 1"]));
        faqFactory.getFAQ(request, (result) => {
            expect(result).toBeDefined();
            expect(result.status_code).toBe(200);
        })
    })
});

Я могу успешно выполнить тестовый пример, но покрытие кода не покрывает ответные вызовы об успешном выполнении или об ошибках

, но тот же тестовый пример работает, если Я изменяю свой API Factory на что-то вроде этого:

const getFAQ = (request, reply) => {
  faqs.findByCondition(request.params.filter).then(success => {
    reply(Response.sendResponse(true, success, ResponseMessages.SUCCESS, StatusCodes.OK));
  }).catch(error => {

    log.error('ERROR : ', error);
    reply(Response.sendResponse(false, error, ResponseMessages.ERROR, 400));
  });
};

Можно ли как-нибудь написать свой тестовый пример, чтобы он покрывал обратные вызовы об успехе / ошибке?

Ответы [ 2 ]

0 голосов
/ 04 марта 2020

Обновление: я нашел решение с помощью библиотеки mockin goose, написав свой тестовый пример следующим образом:

test("test to getFAQ Success", async (done) => {
        const request = {
            params: {
                filter: 'all'
            },
            headers: {
                authorization: testData.authorization
            }
        }
        mockingoose(faqModel.faq).toReturn([], 'find');
        const result = await promisify(faqFactory.getFAQ, request);
        expect(result).toBeDefined();
        expect(result.status).toEqual(200);
        done();
    })
0 голосов
/ 28 февраля 2020

В основном вам нужно будет перезаписать findByCondition, если вы хотите протестировать оба случая и передать обратный вызов на getFAQ

Я немного упростил его, чтобы прояснить то, что я значит.

const getFAQ = (request, reply) => {
  faqs
    .findByCondition(request.params.filter)
    .then(success => {
      reply(true);
    })
    .catch(error => {
      reply(false);
    });
};

const faqs = {
  findByCondition: () => {
    return Promise.resolve();
  }
};

it("works", () => {
  jest.spyOn(faqs, `findByCondition`).mockResolvedValue({});
  getFAQ({ params: { filter: "hello" } }, reply => {
    expect(reply).toBe(true);
  });
});

it("doesn't work", () => {
  jest.spyOn(faqs, `findByCondition`).mockRejectedValue(new Error(`This fails because of error`));
  getFAQ({ params: { filter: "hello" } }, reply => {
    expect(reply).toBe(false);
  });
});


Вы можете увидеть это здесь

...