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
249249Powertools parser utility also bring AWS Lambda event types based on the built-in schema definitions.
250250
251251We 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 {
77 EventBridgeEvent ,
88} from '@aws-lambda-powertools/parser/types' ;
99import { Logger } from '@aws-lambda-powertools/logger' ;
10+ import { EventBridgeEnvelope } from '@aws-lambda-powertools/parser/envelopes' ;
1011
1112const logger = new Logger ( ) ;
1213
@@ -26,7 +27,11 @@ const orderSchema = z.object({
2627type Order = z . infer < typeof orderSchema > ;
2728
2829class 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
Original file line number Diff line number Diff line change @@ -13,4 +13,6 @@ const orderSchema = z.object({
1313 optionalField : z . string ( ) . optional ( ) ,
1414} ) ;
1515
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