GoogleCloudPlatform / GoogleCloudPlatform/functions-framework-nodejs

Testing with TypeScript and TS-Jest

Open
#519 2 comments 9 reactions 0 assignees View on GitHub
bug P2
Dominant language
TypeScript
Stars
1.4k
Forks
181
PR merge metrics
No merged PRs in 30d

Description

Hi there,

I was following the [TypeScript](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/master/docs/typescript.md) and [Testing](https://github.com/GoogleCloudPlatform/functions-framework-nodejs/blob/master/docs/testing-functions.md) guides but I had to work a lot in order to get the tests run with [ts-jest](https://www.npmjs.com/package/ts-jest).

## Setup

This is my setup:

`index.ts` defines the handler

```ts
import { Request, Response, http } from "@google-cloud/functions-framework";

// Register an HTTP function with the Functions Framework

export async function helloHTTPFunction(req: Request, res: Response) {
// Your code here

// Send an HTTP response
res.send("OK");
}

http("helloHTTPFunction", helloHTTPFunction);

```

`index.test.ts` defines the handler's test

```ts
import {
HttpFunction,
Request,
Response,
} from "@google-cloud/functions-framework";
// @ts-ignore
import { getFunction } from "@google-cloud/functions-framework/testing";

describe("HelloTests", () => {
beforeAll(async () => {
// load the module that defines HelloTests
await import("./index");
});

it("is testable", () => {
// get the function using the name it was registered with
const helloHTTPFunction = getFunction(
"helloHTTPFunction"
) as HttpFunction;

// a Request stub with a simple JSON payload
const req = {
body: { foo: "bar" },
} as Request;
// a Response stub that captures the sent response
const res = {
send: (result) => {
// assert the response matches the expected value
expect(result).toBe("OK");
},
} as Response;

// invoke the function
helloHTTPFunction(req, res);
});
});
```

`jest.config.ts` ts-jest config file

```ts
import type { JestConfigWithTsJest } from "ts-jest";

const config: JestConfigWithTsJest = {
preset: "ts-jest",
slowTestThreshold: 5000,
testEnvironment: "node",
silent: true,
modulePathIgnorePatterns: ["/dist/", "/node_modules/"],
testPathIgnorePatterns: [
"/src/fixtures/",
"/dist/",
"/node_modules/",
],
coveragePathIgnorePatterns: [
"/src/fixtures/",
"/dist/",
"/node_modules/",
],
};

export default config;
```

`tsconfig.json` defines TS settings

```json
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "nodenext",
"outDir": "dist",
"esModuleInterop": true,
"strict": true,
"skipLibCheck": true
}
}
```

## Environment

Node 18.12.1
TypeScript 4.9.5
jest 29.4.3
ts-jest 29.0.5
@google-cloud/functions-framework 3.1.3

OS: macOS Ventura on M1 Pro processor

## Error

I get this error when I try to import the `testing` submodule without the `// @ts-ignore` in the test file

![image](https://user-images.githubusercontent.com/2249342/222468223-5c238011-1834-42f1-bb0c-e128356e9efc.png)

I think it's related to [this TypeScript issue](https://github.com/microsoft/TypeScript/issues/33079#issuecomment-1426238391) and the way the package.json is declared in `@google-cloud/functions-framework` module.

The test will also fail if not using the --experimental-vm-modules whith jest, but that's because of the `await import("./index")` statement in the hook.

So you need to add this to the `package.json` scripts

`"test": "NODE_OPTIONS=--experimental-vm-modules jest"`

and then launch `npm test`.

## Workaround

Adding the `// @ts-ignore` does the trick. However, if I am not messing up with the TS settings too much, wouldn't it be nice to have a more TS-friendly testing module package declaration?

And if you think (and I might agree with you) that this issue is more a TS problem than your library's, then could you please extend the documentation by adding a "testing with typescript" section in the docs (feel free to add my workaround if deemed good enough)?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.