测试函数
HTTP 类的函数
该方法适用于所有的类 HTTP 触发器的函数,包括 HTTP
和 API_GATEWAY
。
使用和应用相同的测试方法来测试,针对 HTTP 函数,使用封装了 supertest 的 createHttpRequest
方法创建 HTTP 客户端。
唯一和应用不同的是,使用 createFunctionApp
方法创建函数应用(app)。
createFunctionApp
方法是 createApp
方法在函数场景下的定制(其中指定了函数的 @midwayjs/serverless-app
框架)。
这里不直接使用 @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({
// ...
}));
具体的函数工具方法,可以查阅不同的平台触发器测试。