You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript中对AWS EventBridge事件模式进行单元测试?

实现EventBridge事件模式匹配工具

我们可以基于AWS EventBridge的官方匹配规则,实现一个递归的模式匹配逻辑,封装成工具类供单元测试调用。

核心实现代码(TypeScript)

type EventBridgeEvent = Record<string, any>;
type EventPattern = Record<string, any>;

/**
 * 递归匹配模式片段与事件片段
 */
function matchPattern(patternValue: any, eventValue: any): boolean {
    // 模式值为数组:只要事件值匹配数组中任意一个元素
    if (Array.isArray(patternValue)) {
        // 事件值是数组:检查是否有任意元素匹配模式数组中的任意元素
        if (Array.isArray(eventValue)) {
            return eventValue.some(eventItem => 
                patternValue.some(patternItem => matchPattern(patternItem, eventItem))
            );
        }
        // 事件值是单个值:检查是否匹配模式数组中的任意元素
        return patternValue.some(patternItem => matchPattern(patternItem, eventValue));
    }

    // 模式值为对象:递归匹配每个键值对
    if (typeof patternValue === 'object' && patternValue !== null) {
        if (typeof eventValue !== 'object' || eventValue === null) {
            return false;
        }
        // 模式中的所有键必须在事件中存在且匹配
        return Object.entries(patternValue).every(([key, patternVal]) => {
            const eventVal = eventValue[key];
            if (eventVal === undefined) {
                return false;
            }
            return matchPattern(patternVal, eventVal);
        });
    }

    // 基本类型:精确匹配
    return patternValue === eventValue;
}

export class EventBridgeEmulator {
    /**
     * 验证事件是否符合指定的EventBridge模式
     * @param pattern EventBridge事件模式
     * @param event 待验证的EventBridge事件
     * @returns 是否匹配
     */
    static evaluate(pattern: EventPattern, event: EventBridgeEvent): boolean {
        // 模式中的所有顶级键必须在事件中存在且匹配
        return Object.entries(pattern).every(([key, patternVal]) => {
            const eventVal = event[key];
            if (eventVal === undefined) {
                return false;
            }
            return matchPattern(patternVal, eventVal);
        });
    }
}

单元测试示例

结合你提供的测试框架,编写完整的单元测试:

import { EventBridgeEmulator } from './EventBridgeEmulator';

describe('EventPattern', () => {
    let eventPattern: EventPattern;
    let validEvent: EventBridgeEvent;
    let invalidEvent: EventBridgeEvent;

    beforeAll(() => {
        // 目标匹配模式
        eventPattern = {
            "source": ["aws.access-analyzer"],
            "detail-type": ["Access Analyzer Finding"]
        };

        // 符合模式的事件
        validEvent = {
            "version": "0",
            "id": "22222222-dcba-4444-dcba-333333333333",
            "detail-type": "Access Analyzer Finding",
            "source": "aws.access-analyzer",
            "account": "123456789012",
            "time": "2019-11-21T01:22:33Z",
            "region": "us-west-2",
            "resources": ["arn:aws:access-analyzer:us-west-2:123456789012:analyzer/MyAnalyzer"],
            "detail": {
                "version": "1.0",
                "accountId": "123456789012",
                "region": "us-west-2",
                "isDeleted": false,
                "id": "bbbbaaaa-abcd-1111-abcd-666666666666",
                "status": "ACTIVE",
                "resourceType": "AWS::S3::Bucket",
                "resource": "arn:aws:s3:::my-bucket",
                "createdAt": "2019-11-20T04:58:50Z",
                "analyzedAt": "2019-11-21T01:22:22Z",
                "updatedAt": "2019-11-21T01:14:07Z",
                "principal": {
                    "AWS": "999988887777"
                },
                "action": ["s3:GetObject"],
                "condition": {},
                "isPublic": false
            }
        };

        // 不符合模式的事件(source错误)
        invalidEvent = {
            ...validEvent,
            "source": "aws.s3"
        };
    });

    it('should match a valid event', () => {
        expect(EventBridgeEmulator.evaluate(eventPattern, validEvent)).toBeTruthy();
    });

    it('should not match an invalid event', () => {
        expect(EventBridgeEmulator.evaluate(eventPattern, invalidEvent)).toBeFalsy();
    });

    // 测试嵌套对象和数组匹配
    it('should match pattern with nested detail and array', () => {
        const nestedPattern: EventPattern = {
            "source": ["aws.access-analyzer"],
            "detail": {
                "resourceType": "AWS::S3::Bucket",
                "action": ["s3:GetObject"]
            }
        };

        // 事件的action数组包含多个值,仍匹配
        const eventWithMultipleActions = {
            ...validEvent,
            "detail": {
                ...validEvent.detail,
                "action": ["s3:GetObject", "s3:PutObject"]
            }
        };

        expect(EventBridgeEmulator.evaluate(nestedPattern, eventWithMultipleActions)).toBeTruthy();
    });
});

支持的匹配规则

这个实现覆盖了EventBridge的核心匹配逻辑:

  • 顶级字段精确匹配(支持数组“或”规则)
  • 嵌套对象的递归匹配
  • 数组字段的包含匹配(事件数组只要有一个元素匹配模式值/数组中的任意元素)
  • 基本类型(字符串、数字、布尔)的精确匹配

如果需要扩展支持通配符(如*、?)、前缀/后缀匹配等高级规则,可以在matchPattern函数中添加对应的字符串处理逻辑。

内容的提问来源于stack exchange,提问作者Asimov4

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 16:59:53