Skip to content

Commit c3cd864

Browse files
committed
add testing section to parser
1 parent 5424a22 commit c3cd864

File tree

4 files changed

+141
-1
lines changed

4 files changed

+141
-1
lines changed

docs/utilities/parser.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,51 @@ The package `@types/aws-lambda` is a popular project that contains type definiti
249249
Powertools parser utility also bring AWS Lambda event types based on the built-in schema definitions.
250250

251251
We recommend to use the types provided by the parser utility. If you encounter any issues or have any feedback, please [submit an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose).
252+
253+
## Testing your code
254+
255+
When testing your handler with **parser decorator** you need to use double assetion to bypass TypeScript type checking in your tests.
256+
This is useful when you want to test the handler for invalid payloads or when you want to test the error handling.
257+
If you are you use middy middleware, you don't need to do this.
258+
259+
=== "handlerDecorator.test.ts"
260+
261+
```typescript hl_lines="29"
262+
--8<-- "examples/snippets/parser/unitTestDecorator.ts"
263+
```
264+
265+
1. Use double assertion `as unknown as X` to bypass TypeScript type checking in your tests
266+
267+
=== "handlerDecorator.ts"
268+
269+
```typescript
270+
--8<-- "examples/snippets/parser/decorator.ts"
271+
```
272+
273+
=== "schema.ts"
274+
275+
```typescript"
276+
--8<-- "examples/snippets/parser/schema.ts"
277+
```
278+
279+
This also works when using `safeParse` option.
280+
281+
=== "handlerSafeParse.test.ts"
282+
283+
```typescript hl_lines="24-32 38 48"
284+
--8<-- "examples/snippets/parser/unitTestSafeParse.ts"
285+
```
286+
287+
1. Use double assertion to pass expected types to the handler
288+
289+
=== "handlerSafeParse.ts"
290+
291+
```typescript
292+
--8<-- "examples/snippets/parser/safeParseDecorator.ts"
293+
```
294+
295+
=== "schema.ts"
296+
297+
```typescript"
298+
--8<-- "examples/snippets/parser/schema.ts"
299+
```

examples/snippets/parser/safeParseDecorator.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type {
77
EventBridgeEvent,
88
} from '@aws-lambda-powertools/parser/types';
99
import { Logger } from '@aws-lambda-powertools/logger';
10+
import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes';
1011

1112
const logger = new Logger();
1213

@@ -26,7 +27,11 @@ const orderSchema = z.object({
2627
type Order = z.infer<typeof orderSchema>;
2728

2829
class Lambda implements LambdaInterface {
29-
@parser({ schema: orderSchema, safeParse: true }) // (1)!
30+
@parser({
31+
schema: orderSchema,
32+
envelope: EventBridgeEnvelope,
33+
safeParse: true,
34+
}) // (1)!
3035
public async handler(
3136
event: ParsedResult<EventBridgeEvent, Order>,
3237
_context: Context
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { orderSchema } from 'examples/snippets/parser/schema';
2+
import { Context } from 'aws-lambda';
3+
import { handler } from 'examples/snippets/parser/decorator';
4+
import { z } from 'zod';
5+
6+
describe('Test handler', () => {
7+
type Order = z.infer<typeof orderSchema>;
8+
9+
it('should parse event successfully', async () => {
10+
const testEvent = {
11+
id: 123,
12+
description: 'test',
13+
items: [
14+
{
15+
id: 1,
16+
quantity: 1,
17+
description: 'item1',
18+
},
19+
],
20+
};
21+
22+
await expect(handler(testEvent, {} as Context)).resolves.not.toThrow();
23+
});
24+
25+
it('should throw error if event is invalid', async () => {
26+
const testEvent = { foo: 'bar' };
27+
await expect(
28+
handler(
29+
testEvent as unknown as Order, // (1)!
30+
{} as Context
31+
)
32+
).rejects.toThrow();
33+
});
34+
});
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { orderSchema } from 'examples/snippets/parser/schema';
2+
import { Context } from 'aws-lambda';
3+
import { handler } from 'examples/snippets/parser/safeParseDecorator';
4+
import { z } from 'zod';
5+
import {
6+
ParsedResult,
7+
EventBridgeEvent,
8+
} from '@aws-lambda-powertools/parser/types';
9+
10+
describe('Test handler', () => {
11+
type Order = z.infer<typeof orderSchema>;
12+
13+
it('should parse event successfully', async () => {
14+
const testEvent = {
15+
version: '0',
16+
id: '6a7e8feb-b491-4cf7-a9f1-bf3703467718',
17+
'detail-type': 'OrderPurchased',
18+
source: 'OrderService',
19+
account: '111122223333',
20+
time: '2020-10-22T18:43:48Z',
21+
region: 'us-west-1',
22+
resources: ['some_additional'],
23+
detail: {
24+
id: 10876546789,
25+
description: 'My order',
26+
items: [
27+
{
28+
id: 1015938732,
29+
quantity: 1,
30+
description: 'item xpto',
31+
},
32+
],
33+
},
34+
};
35+
36+
await expect(
37+
handler(
38+
testEvent as unknown as ParsedResult<EventBridgeEvent, Order>, // (1)!
39+
{} as Context
40+
)
41+
).resolves.not.toThrow();
42+
});
43+
44+
it('should throw error if event is invalid', async () => {
45+
const testEvent = { foo: 'bar' };
46+
await expect(
47+
handler(
48+
testEvent as unknown as ParsedResult<EventBridgeEvent, Order>,
49+
{} as Context
50+
)
51+
).rejects.toThrow();
52+
});
53+
});

0 commit comments

Comments
 (0)