У меня возникли проблемы с запуском тестов Jest для моих модулей - у меня есть простой класс точки входа:
import { Callback, CloudFrontRequestEvent, Context, Handler } from "aws-lambda";
import { CloudFrontHandler } from "./CloudFrontHandler";
import { OriginClient } from "./OriginClient";
import { ResponseRenderer } from "./ResponseRenderer";
import { TemplateRenderer } from "./TemplateRenderer";
export class LambdaHandler {
private readonly renderer: TemplateRenderer;
constructor(renderer: TemplateRenderer) {
this.renderer = renderer;
}
public handle: Handler = (event: CloudFrontRequestEvent, _: Context, callback: Callback): void => {
console.info(new CloudFrontHandler(null, null)); // <- just an empty object here! CloudFrontHandler {}
console.info(new OriginClient(null)); // <- properly mocked
console.info(new ResponseRenderer(null, null)); // <- properly mocked
new CloudFrontHandler(
new OriginClient(event.Records[0].cf.request),
new ResponseRenderer(callback, this.renderer),
)
.handle(); // <- because CloudFrontHandler is not mocked, an error occurs here
}
}
По какой-то причине класс CloudFrontHandler
не издевается (OriginClient
и ResponseRenderer
правильно издеваются автоматически). Ниже приведен мой тестовый класс:
import "jest";
import { Callback, CloudFrontRequest, CloudFrontRequestEvent } from "aws-lambda";
import { mocked } from "ts-jest/utils";
import { LambdaHandler, TemplateRenderer } from "../../../main/nodejs";
import { CloudFrontHandler } from "../../../main/nodejs/edge/CloudFrontHandler";
import { OriginClient } from "../../../main/nodejs/edge/OriginClient";
import { ResponseRenderer } from "../../../main/nodejs/edge/ResponseRenderer";
jest.mock("../../../main/nodejs/edge/CloudFrontHandler");
jest.mock("../../../main/nodejs/edge/OriginClient");
jest.mock("../../../main/nodejs/edge/ResponseRenderer");
const MockedCloudFrontHandler = mocked(CloudFrontHandler);
const MockedOriginClient = mocked(OriginClient);
const MockedResponseRenderer = mocked(ResponseRenderer);
describe("LambdaHandler", (): void => {
it("should handle CloudFront request", (): void => {
const templateRenderer: TemplateRenderer = {} as TemplateRenderer;
const callback: Callback = jest.fn() as Callback;
const request: CloudFrontRequest = {} as CloudFrontRequest;
const event: CloudFrontRequestEvent = {
Records: [
{
cf: {
request: request,
},
},
],
} as CloudFrontRequestEvent;
let handler: LambdaHandler = new LambdaHandler(templateRenderer);
handler.handle(event, null, callback)
// todo
expect(MockedCloudFrontHandler).toHaveBeenCalledTimes(1);
expect(MockedOriginClient).toHaveBeenCalledTimes(1);
expect(MockedResponseRenderer).toHaveBeenCalledTimes(1);
});
});
(Я храню исходные файлы и тестовые файлы отдельно, поэтому все эти src/main
src/test
пути)
Есть ли причина, по которой Jest не будет издеваться над этим одним классом модуля?
-редактировать-
Сообщение об ошибке:
TypeError: (intermediate value).handle is not a function
Я использую именно 11.0.0.
Пробовал с 10.13 и 8.15 - то же самое.
Не могли бы вы добавить пример того, как handle
определяется в CloudFrontHandler
?
@ 10101010 Вы, вероятно, только что указали мне на основную причину - это функция стрелки, поэтому в TypeScript она переведена в JavaScript как свойство, назначенное в конструкторе. Я проверю это.
Комментарии под моим вопросом указали мне на основную причину - проблема здесь в том, что CloudFrontHandler.handle
- это функция стрелки, которую TypeScript переводит в свойство, назначенное в конструкторе. Поскольку конструктор автоматически имитируется, функция не назначается. Создание ручного макета для метода .handle()
решает проблему.
Какую версию NodeJS вы используете? Я полагаю, что, возможно, видел ту же проблему здесь, но только на NodeJS 11.x. Старые версии NodeJS работают нормально.