Skip to main content
Version: 3.0.0

测试函数

HTTP 类的函数

该方法适用于所有的类 HTTP 触发器的函数,包括 HTTPAPI_GATEWAY

使用和应用相同的测试方法来测试,针对 HTTP 函数,使用封装了 supertest 的 createHttpRequest 方法创建 HTTP 客户端。

唯一和应用不同的是,使用 createFunctionApp 方法创建函数应用(app)。

createFunctionApp 方法是 createApp 方法在函数场景下的定制(其中指定了函数的 @midwayjs/serverless-app 框架)。

info

这里不直接使用 @midwayjs/faas 框架,而是使用 @midwayjs/serverless-app 框架,因为后者包含了网关模拟到函数调用的系列步骤。

HTTP 测试代码如下:

import { createFunctionApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework, Application } from '@midwayjs/serverless-app';

describe('test/hello_aliyun.test.ts', () => {
let app: Application;

beforeAll(async () => {
// create app
app = await createFunctionApp<Framework>();
});

afterAll(async () => {
await close(app);
});

it('should get result from api gateway trigger', async () => {
const result = await createHttpRequest(app).get('/').query({
name: 'zhangting',
});
expect(result.text).toEqual('hello zhangting');
});
});

普通触发器

除了类 HTTP 触发器之外,我们还有其他比如定时器、对象存储等函数触发器,这些触发器由于和网关关系密切,不能使用 HTTP 行为来测试,而是使用传统的方法调用来做。

通过 createFunctionApp 方法创建函数 app,通过 getServerlessInstance 方法获取类实例,然后通过实例的方法直接调用,传入参数进行测试。

import { createFunctionApp, close, createHttpRequest } from '@midwayjs/mock';
import { Framework, Application } from '@midwayjs/serverless-app';
import { createInitializeContext } from '@midwayjs/serverless-fc-trigger';

describe('test/hello_aliyun.test.ts', () => {
let app: Application;
let instance: HelloAliyunService;

beforeAll(async () => {
// 创建函数 app
app = await createFunctionApp<Framework>(join(__dirname, '../'), {
initContext: createInitializeContext(), // 这里传入了 aliyun 特有的初始化上下文数据
});

// 拿到服务类
instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService);
});

afterAll(async () => {
await close(app);
});

it('should get result from event trigger', async () => {
// 调用函数方法,传入参数
expect(await instance.handleEvent('hello world')).toEqual('hello world');
});
});

平台工具类

Midway 提供了平台工具类,用于快速创建测试数据。

现有的平台工具类包括: | @midwayjs/serverless-fc-trigger | 阿里云触发器模拟 | | --- | --- | | @midwayjs/serverless-sfc-trigger | 腾讯云触发器模拟 |

这些工具类中,提供了一些快速创建初始化数据的方法。

比如,在阿里云函数中,提供了快速创建初始化上下文的方法,我们可以在初始化函数 app 时传入。

import { createInitializeContext } from '@midwayjs/serverless-fc-trigger';

describe('test/hello_aliyun.test.ts', () => {
// ...

beforeAll(async () => {
// 创建函数 app
app = await createFunctionApp<Framework>(join(__dirname, '../'), {
initContext: createInitializeContext(), // 这里传入了 aliyun 特有的初始化上下文数据
});

// ...
});
});

所有的工具方法都支持修改数据,可以通过参数传入,会和默认的数据做合并。比如要修改初始化上下文数据。

import { createInitializeContext } from '@midwayjs/serverless-fc-trigger';

describe('test/hello_aliyun.test.ts', () => {
// ...

beforeAll(async () => {
// 创建函数 app
app = await createFunctionApp<Framework>(join(__dirname, '../'), {
initContext: createInitializeContext({
accountId: 'xxxxxxx', // 可以按照结构,调整数据
}),
});

// ...
});
});

比如创建一个定时任务触发器的数据。

import { createTimerEvent } from '@midwayjs/serverless-fc-trigger';

it('should get result from timer trigger', async () => {
// 拿到服务类
const instance = await app.getServerlessInstance<HelloAliyunService>(HelloAliyunService);
// 调用函数方法,传入参数
await instance.handleTimer(createTimerEvent());
});

这里的 createTimerEvent 方法,会返回一个和平台相符的数据结构。

{
triggerTime: new Date().toJSON(),
triggerName: 'timer',
payload: '',
}

同样的,我们可以传递参数进行覆盖。

 // 调用函数方法,传入参数
await instance.handleTimer(createTimerEvent({
// ...
}));

具体的函数工具方法,可以查阅不同的平台触发器测试。