Repository: Yoctol/bottender
Pull request #541 (2019-11-21 03:15:10)

changed(Context): unify requestContext
unify `requestContext` to 

```ts
type RequestContext = {
  method: string;
  path: string;
  query: Record<string, string>;
  headers: Record<string, string>;
};
```

instead of using `{ req, res }` or `ctx`

It's the first step to make all request serializable.

codecov-io: # [Codecov](https://codecov.io/gh/Yoctol/bottender/pull/541?src=pr&el=h1) Report
> Merging [#541](https://codecov.io/gh/Yoctol/bottender/pull/541?src=pr&el=desc) into [master](https://codecov.io/gh/Yoctol/bottender/commit/1b39864b09e17acc64480fa80348338d79f58c5b?src=pr&el=desc) will **decrease** coverage by `<.01%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/Yoctol/bottender/pull/541/graphs/tree.svg?width=650&token=JX3EGtxYH3&height=150&src=pr)](https://codecov.io/gh/Yoctol/bottender/pull/541?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #541      +/-   ##
==========================================
- Coverage   81.99%   81.99%   -0.01%     
==========================================
  Files          97       97              
  Lines        3949     3948       -1     
  Branches      957      948       -9     
==========================================
- Hits         3238     3237       -1     
- Misses        674      678       +4     
+ Partials       37       33       -4
```


| [Impacted Files](https://codecov.io/gh/Yoctol/bottender/pull/541?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [packages/bottender/src/context/ConsoleContext.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9jb250ZXh0L0NvbnNvbGVDb250ZXh0LnRz) | `100% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/bot/MessengerConnector.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9ib3QvTWVzc2VuZ2VyQ29ubmVjdG9yLnRz) | `91.8% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/context/LineContext.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9jb250ZXh0L0xpbmVDb250ZXh0LnRz) | `72.39% <ø> (ø)` | :arrow_up: |
| [packages/bottender-express/src/createMiddleware.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyLWV4cHJlc3Mvc3JjL2NyZWF0ZU1pZGRsZXdhcmUudHM=) | `100% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/context/MessengerContext.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9jb250ZXh0L01lc3NlbmdlckNvbnRleHQudHM=) | `97.2% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/bot/SlackConnector.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9ib3QvU2xhY2tDb25uZWN0b3IudHM=) | `92.07% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/bot/LineConnector.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9ib3QvTGluZUNvbm5lY3Rvci50cw==) | `92.63% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/bot/TelegramConnector.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9ib3QvVGVsZWdyYW1Db25uZWN0b3IudHM=) | `98.64% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/bot/ConsoleConnector.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy9ib3QvQ29uc29sZUNvbm5lY3Rvci50cw==) | `100% <ø> (ø)` | :arrow_up: |
| [packages/bottender/src/types.ts](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree#diff-cGFja2FnZXMvYm90dGVuZGVyL3NyYy90eXBlcy50cw==) | `100% <ø> (ø)` | :arrow_up: |
| ... and [8 more](https://codecov.io/gh/Yoctol/bottender/pull/541/diff?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/Yoctol/bottender/pull/541?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/Yoctol/bottender/pull/541?src=pr&el=footer). Last update [1b39864...33eaf56](https://codecov.io/gh/Yoctol/bottender/pull/541?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).


Patch:
diff --git a/packages/bottender-express/src/createMiddleware.ts b/packages/bottender-express/src/createMiddleware.ts
index 4db4134b..305550b4 100644
--- a/packages/bottender-express/src/createMiddleware.ts
+++ b/packages/bottender-express/src/createMiddleware.ts
@@ -24,8 +24,10 @@ function createMiddleware(bot: Bot) {
         ...req.body,
       },
       {
-        req,
-        res,
+        method: req.method,
+        path: req.path,
+        query: req.query,
+        headers: req.headers,
       }
     );
     if (response) {
diff --git a/packages/bottender-koa/src/createMiddleware.ts b/packages/bottender-koa/src/createMiddleware.ts
index a05cbe32..e3e072d4 100644
--- a/packages/bottender-koa/src/createMiddleware.ts
+++ b/packages/bottender-koa/src/createMiddleware.ts
@@ -19,7 +19,12 @@ function createMiddleware(bot: Bot) {
         ...request.query,
         ...request.body,
       },
-      ctx
+      {
+        method: request.method,
+        path: request.path,
+        query: request.query,
+        headers: request.headers,
+      }
     );
     if (res) {
       response.set(res.headers || {});
diff --git a/packages/bottender-micro/src/createRequestHandler.ts b/packages/bottender-micro/src/createRequestHandler.ts
index 2af3c696..5dfd306a 100644
--- a/packages/bottender-micro/src/createRequestHandler.ts
+++ b/packages/bottender-micro/src/createRequestHandler.ts
@@ -51,8 +51,10 @@ function createRequestHandler(bot: Bot, config: RouteConfig = {}) {
         ...body,
       },
       {
-        req,
-        res,
+        method: req.method,
+        path: requestPath,
+        query,
+        headers: req.headers,
       }
     );
     if (handlerResponse) {
diff --git a/packages/bottender-restify/src/createMiddleware.ts b/packages/bottender-restify/src/createMiddleware.ts
index 49ca792c..eed65d46 100644
--- a/packages/bottender-restify/src/createMiddleware.ts
+++ b/packages/bottender-restify/src/createMiddleware.ts
@@ -18,8 +18,10 @@ function createMiddleware(bot: Bot) {
         ...req.body,
       },
       {
-        req,
-        res,
+        method: req.method,
+        path: req.path,
+        query: req.query,
+        headers: req.headers,
       }
     );
     if (response) {
diff --git a/packages/bottender/src/bot/Bot.ts b/packages/bottender/src/bot/Bot.ts
index f592beae..5f96b7db 100644
--- a/packages/bottender/src/bot/Bot.ts
+++ b/packages/bottender/src/bot/Bot.ts
@@ -9,7 +9,15 @@ import Context from '../context/Context';
 import MemoryCacheStore from '../cache/MemoryCacheStore';
 import Session from '../session/Session';
 import SessionStore from '../session/SessionStore';
-import { Action, Body, Client, Event, Plugin, Props } from '../types';
+import {
+  Action,
+  Body,
+  Client,
+  Event,
+  Plugin,
+  Props,
+  RequestContext,
+} from '../types';
 
 import { Connector } from './Connector';
 
@@ -57,7 +65,7 @@ export function run<C extends Client, E extends Event>(
 
 type RequestHandler<B> = (
   body: B,
-  requestContext?: Record<string, any> | null
+  requestContext?: RequestContext
 ) => void | Promise<void>;
 
 export default class Bot<B extends Body, C extends Client, E extends Event> {
@@ -159,10 +167,7 @@ export default class Bot<B extends Body, C extends Client, E extends Event> {
       this._emitter.on('error', console.error);
     }
 
-    return async (
-      body: B,
-      requestContext?: Record<string, any> | null
-    ): Promise<any> => {
+    return async (body: B, requestContext?: RequestContext): Promise<any> => {
       if (!body) {
         throw new Error('Bot.createRequestHandler: Missing argument.');
       }
diff --git a/packages/bottender/src/bot/Connector.ts b/packages/bottender/src/bot/Connector.ts
index fd1d7f44..82e3561f 100644
--- a/packages/bottender/src/bot/Connector.ts
+++ b/packages/bottender/src/bot/Connector.ts
@@ -1,21 +1,19 @@
 import EventEmitter from 'events';
 
 import Session from '../session/Session';
+import { RequestContext } from '../types';
 
 export interface Connector<B, C> {
   client: C;
   platform: string;
-  getUniqueSessionKey(
-    body: B,
-    requestContext?: Record<string, any> | null
-  ): string | null;
+  getUniqueSessionKey(body: B, requestContext?: RequestContext): string | null;
   updateSession(session: Session, body: B): Promise<void>;
   mapRequestToEvents(body: B): any[];
   createContext(params: {
     event: any;
     session?: Session | null;
     initialState?: Record<string, any> | null;
-    requestContext?: Record<string, any> | null;
+    requestContext?: RequestContext;
     emitter?: EventEmitter | null;
   }): any;
 }
diff --git a/packages/bottender/src/bot/ConsoleConnector.ts b/packages/bottender/src/bot/ConsoleConnector.ts
index 1637d887..487b6fd2 100644
--- a/packages/bottender/src/bot/ConsoleConnector.ts
+++ b/packages/bottender/src/bot/ConsoleConnector.ts
@@ -4,6 +4,7 @@ import ConsoleContext from '../context/ConsoleContext';
 import ConsoleEvent, { ConsoleRawEvent } from '../context/ConsoleEvent';
 import Session from '../session/Session';
 import { ConsoleClient } from '../context/ConsoleClient';
+import { RequestContext } from '../types';
 
 import { Connector } from './Connector';
 
@@ -75,7 +76,7 @@ export default class ConsoleConnector
     event: ConsoleEvent;
     session: Session | null;
     initialState?: Record<string, any> | null;
-    requestContext?: Record<string, any> | null;
+    requestContext?: RequestContext;
     emitter: EventEmitter | null;
   }): ConsoleContext {
     return new ConsoleContext({
diff --git a/packages/bottender/src/bot/LineConnector.ts b/packages/bottender/src/bot/LineConnector.ts
index 9205d05d..ae6a1849 100644
--- a/packages/bottender/src/bot/LineConnector.ts
+++ b/packages/bottender/src/bot/LineConnector.ts
@@ -7,6 +7,7 @@ import { LineClient } from 'messaging-api-line';
 import LineContext from '../context/LineContext';
 import LineEvent, { LineRawEvent } from '../context/LineEvent';
 import Session from '../session/Session';
+import { RequestContext } from '../types';
 
 import { Connector } from './Connector';
 
@@ -264,7 +265,7 @@ export default class LineConnector
     event: LineEvent;
     session?: Session | null;
     initialState?: Record<string, any> | null;
-    requestContext?: Record<string, any> | null;
+    requestContext?: RequestContext;
     emitter?: EventEmitter | null;
   }): Promise<LineContext> {
     let customAccessToken;
diff --git a/packages/bottender/src/bot/MessengerConnector.ts b/packages/bottender/src/bot/MessengerConnector.ts
index bfec953c..02ef4aed 100644
--- a/packages/bottender/src/bot/MessengerConnector.ts
+++ b/packages/bottender/src/bot/MessengerConnector.ts
@@ -22,6 +22,7 @@ import MessengerEvent, {
   TakeThreadControl,
 } from '../context/MessengerEvent';
 import Session from '../session/Session';
+import { RequestContext } from '../types';
 
 import { Connector } from './Connector';
 
@@ -333,7 +334,7 @@ export default class MessengerConnector
     event: MessengerEvent;
     session?: Session;
     initialState?: Record<string, any>;
-    requestContext?: Record<string, any>;
+    requestContext?: RequestContext;
     emitter?: EventEmitter;
   }): Promise<MessengerContext> {
     let customAccessToken;
diff --git a/packages/bottender/src/bot/SlackConnector.ts b/packages/bottender/src/bot/SlackConnector.ts
index a962c73e..84f7b962 100644
--- a/packages/bottender/src/bot/SlackConnector.ts
+++ b/packages/bottender/src/bot/SlackConnector.ts
@@ -14,6 +14,7 @@ import SlackEvent, {
   Message,
   SlackRawEvent,
 } from '../context/SlackEvent';
+import { RequestContext } from '../types';
 
 import { Connector } from './Connector';
 
@@ -300,7 +301,7 @@ export default class SlackConnector
     event: SlackEvent;
     session: Session | null;
     initialState?: Record<string, any> | null;
-    requestContext?: Record<string, any> | null;
+    requestContext?: RequestContext;
     emitter?: EventEmitter | null;
   }): SlackContext {
     return new SlackContext({
diff --git a/packages/bottender/src/bot/TelegramConnector.ts b/packages/bottender/src/bot/TelegramConnector.ts
index ac537d84..7ca2a4ca 100644
--- a/packages/bottender/src/bot/TelegramConnector.ts
+++ b/packages/bottender/src/bot/TelegramConnector.ts
@@ -5,6 +5,7 @@ import { TelegramClient } from 'messaging-api-telegram';
 import Session from '../session/Session';
 import TelegramContext from '../context/TelegramContext';
 import TelegramEvent, { TelegramRawEvent } from '../context/TelegramEvent';
+import { RequestContext } from '../types';
 
 import { Connector } from './Connector';
 
@@ -168,7 +169,7 @@ export default class TelegramConnector
     event: TelegramEvent;
     session: Session | null;
     initialState?: Record<string, any> | null;
-    requestContext?: Record<string, any> | null;
+    requestContext?: RequestContext;
     emitter?: EventEmitter | null;
   }): TelegramContext {
     return new TelegramContext({
diff --git a/packages/bottender/src/bot/ViberConnector.ts b/packages/bottender/src/bot/ViberConnector.ts
index 78634a37..9d0c1fbb 100644
--- a/packages/bottender/src/bot/ViberConnector.ts
+++ b/packages/bottender/src/bot/ViberConnector.ts
@@ -7,6 +7,7 @@ import { addedDiff } from 'deep-object-diff';
 import Session from '../session/Session';
 import ViberContext from '../context/ViberContext';
 import ViberEvent, { ViberRawEvent } from '../context/ViberEvent';
+import { RequestContext } from '../types';
 
 import { Connector } from './Connector';
 
@@ -129,7 +130,7 @@ export default class ViberConnector
     event: ViberEvent;
     session: Session | null;
     initialState?: Record<string, any> | null;
-    requestContext?: Record<string, any> | null;
+    requestContext?: RequestContext;
     emitter?: EventEmitter | null;
   }): ViberContext {
     return new ViberContext({
diff --git a/packages/bottender/src/context/ConsoleContext.ts b/packages/bottender/src/context/ConsoleContext.ts
index 20010a92..444c8a1f 100644
--- a/packages/bottender/src/context/ConsoleContext.ts
+++ b/packages/bottender/src/context/ConsoleContext.ts
@@ -3,6 +3,7 @@ import EventEmitter from 'events';
 import sleep from 'delay';
 
 import Session from '../session/Session';
+import { RequestContext } from '../types';
 
 import ConsoleEvent from './ConsoleEvent';
 import Context from './Context';
@@ -14,7 +15,7 @@ type Options = {
   event: ConsoleEvent;
   session: Session | null;
   initialState?: Record<string, any> | null;
-  requestContext?: Record<string, any> | null;
+  requestContext?: RequestContext;
   fallbackMethods: boolean;
   mockPlatform: string;
   emitter: EventEmitter | null;
diff --git a/packages/bottender/src/context/Context.ts b/packages/bottender/src/context/Context.ts
index 9f917218..491b8ee2 100644
--- a/packages/bottender/src/context/Context.ts
+++ b/packages/bottender/src/context/Context.ts
@@ -4,7 +4,7 @@ import cloneDeep from 'lodash/cloneDeep';
 import debug from 'debug';
 import warning from 'warning';
 
-import { Client, Event } from '../types';
+import { Client, Event, RequestContext } from '../types';
 
 const debugContext = debug('bottender:context');
 
@@ -13,7 +13,7 @@ type Options<C extends Client, E extends Event> = {
   event: E;
   session: any;
   initialState?: Record<string, any> | null;
-  requestContext?: Record<string, any> | null;
+  requestContext?: RequestContext;
   emitter?: EventEmitter | null;
 };
 
@@ -36,7 +36,7 @@ export default class Context<C extends Client, E extends Event> {
 
   _initialState?: Record<string, any> | null;
 
-  _requestContext: Record<string, any> | null;
+  _requestContext: RequestContext | null;
 
   _emitter: EventEmitter | null;
 
diff --git a/packages/bottender/src/context/LineContext.ts b/packages/bottender/src/context/LineContext.ts
index c346f992..4f694e4f 100644
--- a/packages/bottender/src/context/LineContext.ts
+++ b/packages/bottender/src/context/LineContext.ts
@@ -7,6 +7,7 @@ import warning from 'warning';
 import { Line, LineClient, LineTypes } from 'messaging-api-line';
 
 import Session from '../session/Session';
+import { RequestContext } from '../types';
 
 import Context from './Context';
 import LineEvent from './LineEvent';
@@ -17,7 +18,7 @@ type Options = {
   event: LineEvent;
   session?: Session | null;
   initialState?: Record<string, any> | null;
-  requestContext?: Record<string, any> | null;
+  requestContext?: RequestContext;
   customAccessToken?: string;
   shouldBatch?: boolean;
   sendMethod?: string;
diff --git a/packages/bottender/src/context/MessengerContext.ts b/packages/bottender/src/context/MessengerContext.ts
index 147d5d2d..1a84b57e 100644
--- a/packages/bottender/src/context/MessengerContext.ts
+++ b/packages/bottender/src/context/MessengerContext.ts
@@ -6,6 +6,7 @@ import warning from 'warning';
 import { MessengerBatch, MessengerClient } from 'messaging-api-messenger';
 
 import Session from '../session/Session';
+import { RequestContext } from '../types';
 
 import Context from './Context';
 import MessengerEvent from './MessengerEvent';
@@ -17,7 +18,7 @@ type Options = {
   event: MessengerEvent;
   session?: Session;
   initialState?: Record<string, any>;
-  requestContext?: Record<string, any>;
+  requestContext?: RequestContext;
   customAccessToken?: string;
   batchQueue?: Record<string, any> | null;
   emitter?: EventEmitter;
diff --git a/packages/bottender/src/types.ts b/packages/bottender/src/types.ts
index c817e574..62c532b8 100644
--- a/packages/bottender/src/types.ts
+++ b/packages/bottender/src/types.ts
@@ -133,3 +133,10 @@ export type BottenderConfig = {
     };
   };
 };
+
+export type RequestContext = {
+  method: string;
+  path: string;
+  query: Record<string, string>;
+  headers: Record<string, string>;
+};


Test patch:
diff --git a/packages/bottender-express/src/__tests__/createMiddleware.spec.ts b/packages/bottender-express/src/__tests__/createMiddleware.spec.ts
index 588a8576..3c7fd893 100644
--- a/packages/bottender-express/src/__tests__/createMiddleware.spec.ts
+++ b/packages/bottender-express/src/__tests__/createMiddleware.spec.ts
@@ -38,8 +38,11 @@ it('should merge query and body then pass into requestHandler', async () => {
   const middleware = createMiddleware(bot);
 
   const req = {
+    method: 'post',
+    path: '/',
     query: { a: '1' },
     body: { b: 2 },
+    headers: {},
   };
   const res = {
     send: jest.fn(),
@@ -49,7 +52,15 @@ it('should merge query and body then pass into requestHandler', async () => {
 
   await middleware(req, res, next);
 
-  expect(requestHandler).toBeCalledWith({ a: '1', b: 2 }, { req, res });
+  expect(requestHandler).toBeCalledWith(
+    { a: '1', b: 2 },
+    {
+      method: 'post',
+      path: '/',
+      query: { a: '1' },
+      headers: {},
+    }
+  );
 });
 
 it('should overwrite query value if this key exists in body', async () => {
@@ -59,8 +70,11 @@ it('should overwrite query value if this key exists in body', async () => {
   const middleware = createMiddleware(bot);
 
   const req = {
+    method: 'post',
+    path: '/',
     query: { a: '1' },
     body: { a: 2 },
+    headers: {},
   };
   const res = {
     send: jest.fn(),
@@ -70,7 +84,15 @@ it('should overwrite query value if this key exists in body', async () => {
 
   await middleware(req, res, next);
 
-  expect(requestHandler).toBeCalledWith({ a: 2 }, { req, res });
+  expect(requestHandler).toBeCalledWith(
+    { a: 2 },
+    {
+      method: 'post',
+      path: '/',
+      query: { a: '1' },
+      headers: {},
+    }
+  );
 });
 
 it('should response 200 if there is response return from requestHandler', async () => {
diff --git a/packages/bottender-koa/src/__tests__/createMiddleware.spec.ts b/packages/bottender-koa/src/__tests__/createMiddleware.spec.ts
index 2e515730..66182223 100644
--- a/packages/bottender-koa/src/__tests__/createMiddleware.spec.ts
+++ b/packages/bottender-koa/src/__tests__/createMiddleware.spec.ts
@@ -32,15 +32,26 @@ it('should merge query and body then pass into requestHandler', async () => {
   const middleware = createMiddleware(bot);
 
   const request = {
+    method: 'post',
+    path: '/',
     query: { a: '1' },
     body: { b: 2 },
+    headers: {},
   };
   const response = {};
   const ctx = { request, response };
 
   await middleware(ctx);
 
-  expect(requestHandler).toBeCalledWith({ a: '1', b: 2 }, ctx);
+  expect(requestHandler).toBeCalledWith(
+    { a: '1', b: 2 },
+    {
+      method: 'post',
+      path: '/',
+      query: { a: '1' },
+      headers: {},
+    }
+  );
 });
 
 it('should overwrite query value if this key exists in body', async () => {
@@ -50,15 +61,26 @@ it('should overwrite query value if this key exists in body', async () => {
   const middleware = createMiddleware(bot);
 
   const request = {
+    method: 'post',
+    path: '/',
     query: { a: '1' },
     body: { a: 2 },
+    headers: {},
   };
   const response = {};
   const ctx = { request, response };
 
   await middleware(ctx);
 
-  expect(requestHandler).toBeCalledWith({ a: 2 }, ctx);
+  expect(requestHandler).toBeCalledWith(
+    { a: 2 },
+    {
+      method: 'post',
+      path: '/',
+      query: { a: '1' },
+      headers: {},
+    }
+  );
 });
 
 it('should response 200 if there is response return from requestHandler', async () => {
diff --git a/packages/bottender-restify/src/__tests__/createMiddleware.spec.ts b/packages/bottender-restify/src/__tests__/createMiddleware.spec.ts
index e1aa0c7c..578a8344 100644
--- a/packages/bottender-restify/src/__tests__/createMiddleware.spec.ts
+++ b/packages/bottender-restify/src/__tests__/createMiddleware.spec.ts
@@ -36,8 +36,11 @@ it('should merge query and body then pass into requestHandler', async () => {
   const middleware = createMiddleware(bot);
 
   const req = {
+    method: 'post',
+    path: '/',
     query: { a: '1' },
     body: { b: 2 },
+    headers: {},
   };
   const res = {
     send: jest.fn(),
@@ -46,7 +49,15 @@ it('should merge query and body then pass into requestHandler', async () => {
 
   await middleware(req, res, next);
 
-  expect(requestHandler).toBeCalledWith({ a: '1', b: 2 }, { req, res });
+  expect(requestHandler).toBeCalledWith(
+    { a: '1', b: 2 },
+    {
+      method: 'post',
+      path: '/',
+      query: { a: '1' },
+      headers: {},
+    }
+  );
 });
 
 it('should overwrite query value if this key exists in body', async () => {
@@ -56,8 +67,11 @@ it('should overwrite query value if this key exists in body', async () => {
   const middleware = createMiddleware(bot);
 
   const req = {
+    method: 'post',
+    path: '/',
     query: { a: '1' },
     body: { a: 2 },
+    headers: {},
   };
   const res = {
     send: jest.fn(),
@@ -66,7 +80,15 @@ it('should overwrite query value if this key exists in body', async () => {
 
   await middleware(req, res, next);
 
-  expect(requestHandler).toBeCalledWith({ a: 2 }, { req, res });
+  expect(requestHandler).toBeCalledWith(
+    { a: 2 },
+    {
+      method: 'post',
+      path: '/',
+      query: { a: '1' },
+      headers: {},
+    }
+  );
 });
 
 it('should response 200 if there is response return from requestHandler', async () => {
diff --git a/packages/bottender/src/context/__tests__/Context.spec.ts b/packages/bottender/src/context/__tests__/Context.spec.ts
index ec166857..0b87df0a 100644
--- a/packages/bottender/src/context/__tests__/Context.spec.ts
+++ b/packages/bottender/src/context/__tests__/Context.spec.ts
@@ -169,7 +169,12 @@ describe('request context', () => {
     });
 
     it('should support get requestContext', () => {
-      const requestContext = { req: {}, res: {} };
+      const requestContext = {
+        method: 'post',
+        path: '/',
+        query: {},
+        headers: {},
+      };
 
       const { context } = setup({ requestContext });
 
diff --git a/packages/bottender/src/test-utils/ContextSimulator.ts b/packages/bottender/src/test-utils/ContextSimulator.ts
index 9ef7388b..7aacb901 100644
--- a/packages/bottender/src/test-utils/ContextSimulator.ts
+++ b/packages/bottender/src/test-utils/ContextSimulator.ts
@@ -125,7 +125,7 @@ class ContextSimulator {
         _state: state || this._initialState,
       },
       initialState: this._initialState,
-      requestContext: {},
+      requestContext: undefined,
       emitter: null,
     });