File tree Expand file tree Collapse file tree 7 files changed +194
-2
lines changed Expand file tree Collapse file tree 7 files changed +194
-2
lines changed Original file line number Diff line number Diff line change @@ -249,3 +249,51 @@ The package `@types/aws-lambda` is a popular project that contains type definiti
249
249
Powertools parser utility also bring AWS Lambda event types based on the built-in schema definitions.
250
250
251
251
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** ] ( #parse-events ) 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="26"
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/handlerDecorator.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="21-29 35 45"
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/handlerSafeParseDecorator.ts"
293
+ ```
294
+
295
+ === "schema.ts"
296
+
297
+ ```typescript
298
+ --8<-- "examples/snippets/parser/schema.ts"
299
+ ```
Original file line number Diff line number Diff line change
1
+ import type { Context } from 'aws-lambda' ;
2
+ import type { LambdaInterface } from '@aws-lambda-powertools/commons/types' ;
3
+ import { parser } from '@aws-lambda-powertools/parser' ;
4
+ import { Logger } from '@aws-lambda-powertools/logger' ;
5
+ import { orderSchema , type Order } from './schema.js' ;
6
+
7
+ const logger = new Logger ( ) ;
8
+
9
+ class Lambda implements LambdaInterface {
10
+ @parser ( { schema : orderSchema } )
11
+ public async handler ( event : Order , _context : Context ) : Promise < number > {
12
+ logger . info ( 'Processing event' , { event } ) ;
13
+
14
+ // ... business logic
15
+ return event . id ;
16
+ }
17
+ }
18
+
19
+ const myFunction = new Lambda ( ) ;
20
+ export const handler = myFunction . handler . bind ( myFunction ) ;
Original file line number Diff line number Diff line change
1
+ import type { Context } from 'aws-lambda' ;
2
+ import type { LambdaInterface } from '@aws-lambda-powertools/commons/types' ;
3
+ import { parser } from '@aws-lambda-powertools/parser' ;
4
+ import { Logger } from '@aws-lambda-powertools/logger' ;
5
+ import { orderSchema , type Order } from './schema.js' ;
6
+ import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes' ;
7
+ import type {
8
+ ParsedResult ,
9
+ EventBridgeEvent ,
10
+ } from '@aws-lambda-powertools/parser/types' ;
11
+
12
+ const logger = new Logger ( ) ;
13
+
14
+ class Lambda implements LambdaInterface {
15
+ @parser ( {
16
+ schema : orderSchema ,
17
+ envelope : EventBridgeEnvelope ,
18
+ safeParse : true ,
19
+ } )
20
+ public async handler (
21
+ event : ParsedResult < EventBridgeEvent , Order > ,
22
+ _context : Context
23
+ ) : Promise < number > {
24
+ logger . info ( 'Processing event' , { event } ) ;
25
+ if ( event . success ) {
26
+ // ... business logic
27
+ return event . data . id ;
28
+ } else {
29
+ logger . error ( 'Failed to parse event' , { event } ) ;
30
+ throw new Error ( 'Failed to parse event' ) ;
31
+ }
32
+ }
33
+ }
34
+
35
+ const myFunction = new Lambda ( ) ;
36
+ export const handler = myFunction . handler . bind ( myFunction ) ;
Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ import type {
7
7
EventBridgeEvent ,
8
8
} from '@aws-lambda-powertools/parser/types' ;
9
9
import { Logger } from '@aws-lambda-powertools/logger' ;
10
+ import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes' ;
10
11
11
12
const logger = new Logger ( ) ;
12
13
@@ -26,7 +27,11 @@ const orderSchema = z.object({
26
27
type Order = z . infer < typeof orderSchema > ;
27
28
28
29
class Lambda implements LambdaInterface {
29
- @parser ( { schema : orderSchema , safeParse : true } ) // (1)!
30
+ @parser ( {
31
+ schema : orderSchema ,
32
+ envelope : EventBridgeEnvelope ,
33
+ safeParse : true ,
34
+ } ) // (1)!
30
35
public async handler (
31
36
event : ParsedResult < EventBridgeEvent , Order > ,
32
37
_context : Context
Original file line number Diff line number Diff line change @@ -13,4 +13,6 @@ const orderSchema = z.object({
13
13
optionalField : z . string ( ) . optional ( ) ,
14
14
} ) ;
15
15
16
- export { orderSchema } ;
16
+ type Order = z . infer < typeof orderSchema > ;
17
+
18
+ export { orderSchema , type Order } ;
Original file line number Diff line number Diff line change
1
+ import type { Context } from 'aws-lambda' ;
2
+ import type { Order } from './schema.js' ;
3
+ import { handler } from './decorator.js' ;
4
+
5
+ describe ( 'Test handler' , ( ) => {
6
+ it ( 'should parse event successfully' , async ( ) => {
7
+ const testEvent = {
8
+ id : 123 ,
9
+ description : 'test' ,
10
+ items : [
11
+ {
12
+ id : 1 ,
13
+ quantity : 1 ,
14
+ description : 'item1' ,
15
+ } ,
16
+ ] ,
17
+ } ;
18
+
19
+ await expect ( handler ( testEvent , { } as Context ) ) . resolves . toEqual ( 123 ) ;
20
+ } ) ;
21
+
22
+ it ( 'should throw error if event is invalid' , async ( ) => {
23
+ const testEvent = { foo : 'bar' } ;
24
+ await expect (
25
+ handler (
26
+ testEvent as unknown as Order , // (1)!
27
+ { } as Context
28
+ )
29
+ ) . rejects . toThrow ( ) ;
30
+ } ) ;
31
+ } ) ;
Original file line number Diff line number Diff line change
1
+ import type { Order } from './schema.js' ;
2
+ import type { Context } from 'aws-lambda' ;
3
+ import { handler } from './safeParseDecorator.js' ;
4
+ import {
5
+ ParsedResult ,
6
+ EventBridgeEvent ,
7
+ } from '@aws-lambda-powertools/parser/types' ;
8
+
9
+ describe ( 'Test handler' , ( ) => {
10
+ it ( 'should parse event successfully' , async ( ) => {
11
+ const testEvent = {
12
+ version : '0' ,
13
+ id : '6a7e8feb-b491-4cf7-a9f1-bf3703467718' ,
14
+ 'detail-type' : 'OrderPurchased' ,
15
+ source : 'OrderService' ,
16
+ account : '111122223333' ,
17
+ time : '2020-10-22T18:43:48Z' ,
18
+ region : 'us-west-1' ,
19
+ resources : [ 'some_additional' ] ,
20
+ detail : {
21
+ id : 10876546789 ,
22
+ description : 'My order' ,
23
+ items : [
24
+ {
25
+ id : 1015938732 ,
26
+ quantity : 1 ,
27
+ description : 'item xpto' ,
28
+ } ,
29
+ ] ,
30
+ } ,
31
+ } ;
32
+
33
+ await expect (
34
+ handler (
35
+ testEvent as unknown as ParsedResult < EventBridgeEvent , Order > , // (1)!
36
+ { } as Context
37
+ )
38
+ ) . resolves . toEqual ( 10876546789 ) ;
39
+ } ) ;
40
+
41
+ it ( 'should throw error if event is invalid' , async ( ) => {
42
+ const testEvent = { foo : 'bar' } ;
43
+ await expect (
44
+ handler (
45
+ testEvent as unknown as ParsedResult < EventBridgeEvent , Order > ,
46
+ { } as Context
47
+ )
48
+ ) . rejects . toThrow ( ) ;
49
+ } ) ;
50
+ } ) ;
You can’t perform that action at this time.
0 commit comments