У меня есть проект NestJS, над которым я работаю, и мне нужно написать модульные тесты моих сервисов.
У меня есть служба BigQueryService, которая использует @ google-cloud / bigquery для доступа к набору данных Big Query и выполнения запроса. У меня также есть другой сервис (назовем его MyService), задача которого - построить запрос, который мне нужен, в зависимости от какой-то другой логики, и передать его в BigQueryService, получить от него результат запроса и вернуть его контроллеру, который будет ввключите отправку данных через конечную точку.
Мне нужно написать модульные тесты для MyService, и для этого мне нужно смоделировать BigQueryService таким образом, чтобы он не требовал разрешения зависимостей BigQueryService. Вот мой код:
bigquery.service.ts:
import { Injectable } from '@nestjs/common';
import { BigQuery } from '@google-cloud/bigquery';
...
@Injectable()
export class BigqueryService {
...
constructor(
...
) {
...
}
async executeQuery(querySentence: string): Promise<Array<any>> {
...
return response;
}
}
MyService.service.ts:
import { Injectable } from '@nestjs/common';
import { BigqueryService } from '../bigquery/bigquery.service';
//the following is just a service that helps log the results of this service
import { MyLogger } from '../../config-service/logger.service';
...
@Injectable()
export class MyService {
constructor(
private readonly bigqueryService: BigqueryService,
private readonly logger: MyLogger,
) { }
...
async myFunc(request: RequestInterface): Promise<Array<ResponseInterface>> {
let query = (some code to create a query i want)
return await this.bigqueryService.executeQuery(query);
}
Для тестов я следовал за ответамив этой ветке: Макет метода сервиса, вызываемого тестируемым при использовании Jest
jest.mock('../services/bigquery/bigquery.service', () => jest.fn())
const bq = require('../services/bigquery/bigquery.service')
jest.mock('../config-service/logger.service', () => jest.fn())
const ml = require('../config-service/logger.service')
const executeQuery = jest.fn()
executeQuery.mockReturnValue('desired value')
bq.mockImplementation(() => ({executeQuery}))
describe("Testing consumption moment service function", () => {
it("should call the mock service", () => {
const ms = new MyService(bq,ml)
ms.myFunc(requestBody) //requestBody is a RequestInterface
expect(bq.executeQuery).toHaveBeenCalled
expect(bq.executeQuery).toHaveReturned
});
});
Этот тест пройден, поэтому я предполагаю, что правильно издевался над сервисом bigquery. Но когда я пытаюсь утверждать, что возвращаемое значение является правильным, я делаю тест асинхронным, чтобы тест не завершился, пока myFunc фактически не завершится, и у меня может быть результат для сравнения.
it("should call the mock service", async () => {
const ms = new MyService(bq,ml)
await ms.myFunc(requestBody)
expect(bq.executeQuery).toHaveBeenCalled
expect(bq.executeQuery).toHaveReturned
});
Это приводит к ошибке: Ошибка типа: this.bigqueryService.executeQuery не является функцией Ошибка указывает на строку, где myFunc вызывает this.bigqueryService.executeQuery.
Я пробовал разные примеры насмешек, чтобы можно было смоделировать вызов этой функции, но ни один из них не подошел так близко, как в примере выше. Я также пытался использовать
jest.spyOn(bq, 'executeQuery')
Но это также сказало, что executeQuery не был функцией: Невозможно следить за свойством executeQuery, поскольку оно не является функцией;вместо этого дано неопределенное значение
Может ли кто-нибудь указать мне правильное направление здесь? Что-то мне не хватает, чтобы этот тест работал? Я заранее благодарю всех за любую помощь, которую вы можете оказать мне.