在C# .NET中模拟AWS ScheduledEvent并验证Detail属性问题
验证AWS ScheduledEvent的Detail属性匹配EventBatchData的问题
问题背景
需要验证AWS ScheduledEvent对象的Detail属性数据是否符合要求,该数据来自EventBridge,Detail的JSON结构需与EventBatchData类匹配。EventBatchData类定义如下:
public class EventBatchData { public int BatchSize { get; private set; } public int BatchRetries { get; private set; } public EventBatchData(int batchSize, int batchRetries) { BatchSize = batchSize; BatchRetries = batchRetries; var validator = new EventBatchDataValidator(); validator.ValidateAndThrow(this); } }
已通过FluentValidation确保EventBatchData不会处于无效状态,但无法直接设置ScheduledEvent.Detail属性,尝试使用dynamic类型赋值失败,测试代码如下:
[Theory] [AutoFakeItEasyData] public void NotThrowError_WhenDetailIsValid(EventBatchData eventBatchData) { //Arrange dynamic expectedDetail = new ExpandoObject(); expectedDetail.BatchRetries = eventBatchData.BatchRetries; expectedDetail.BatchSize = eventBatchData.BatchSize; var scheduledEvent = new ScheduledEvent { Account = "testAccount", Region = "testRegion", DetailType = "Scheduled Event", Source = "aws.events", Time = DateTime.UtcNow, Id = "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c", Resources = new List<string> { "resource1", "resource2" }, Detail = expectedDetail }; //Act var result = _validator.TestValidate(scheduledEvent); //Assert result.ShouldHaveValidationErrorFor(x => x.Detail); }
报错信息
无法将类型“System.Dynamic.ExpandoObject”隐式转换为“Amazon.Lambda.CloudWatchEvents.ScheduledEvents.Detail”
解决方案
1. 使用泛型版本的ScheduledEvent
AWS Lambda的ScheduledEvent提供了泛型版本ScheduledEvent<T>,可直接指定Detail的类型为EventBatchData,无需动态类型转换:
[Theory] [AutoFakeItEasyData] public void NotThrowError_WhenDetailIsValid(EventBatchData eventBatchData) { //Arrange var scheduledEvent = new ScheduledEvent<EventBatchData> { Account = "testAccount", Region = "testRegion", DetailType = "Scheduled Event", Source = "aws.events", Time = DateTime.UtcNow, Id = "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c", Resources = new List<string> { "resource1", "resource2" }, Detail = eventBatchData }; //Act var result = _validator.TestValidate(scheduledEvent); //Assert result.ShouldNotHaveValidationErrorFor(x => x.Detail); }
2. 序列化EventBatchData为JSON再反序列化为Detail
如果必须使用非泛型ScheduledEvent,可将EventBatchData序列化为JSON字符串,再反序列化为Detail类型:
using System.Text.Json; [Theory] [AutoFakeItEasyData] public void NotThrowError_WhenDetailIsValid(EventBatchData eventBatchData) { //Arrange var detailJson = JsonSerializer.Serialize(eventBatchData); var detail = JsonSerializer.Deserialize<Detail>(detailJson); var scheduledEvent = new ScheduledEvent { Account = "testAccount", Region = "testRegion", DetailType = "Scheduled Event", Source = "aws.events", Time = DateTime.UtcNow, Id = "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c", Resources = new List<string> { "resource1", "resource2" }, Detail = detail }; //Act var result = _validator.TestValidate(scheduledEvent); //Assert result.ShouldNotHaveValidationErrorFor(x => x.Detail); }
3. 直接构造Detail对象并赋值属性
Detail类支持动态属性赋值,可直接实例化后设置对应属性:
[Theory] [AutoFakeItEasyData] public void NotThrowError_WhenDetailIsValid(EventBatchData eventBatchData) { //Arrange var detail = new Detail(); detail.BatchSize = eventBatchData.BatchSize; detail.BatchRetries = eventBatchData.BatchRetries; var scheduledEvent = new ScheduledEvent { Account = "testAccount", Region = "testRegion", DetailType = "Scheduled Event", Source = "aws.events", Time = DateTime.UtcNow, Id = "cdc73f9d-aea9-11e3-9d5a-835b769c0d9c", Resources = new List<string> { "resource1", "resource2" }, Detail = detail }; //Act var result = _validator.TestValidate(scheduledEvent); //Assert result.ShouldNotHaveValidationErrorFor(x => x.Detail); }
内容的提问来源于stack exchange,提问作者TortillaCurtain
相关产品推荐
相关产品推荐

