Azure.Messaging.EventGrid中IotHubDeviceTelemetryEventData无构造函数?单元测试受阻
解决Azure.Messaging.EventGrid中IotHubDeviceTelemetryEventData的单元测试问题
针对新版Azure.Messaging.EventGrid中IotHubDeviceTelemetryEventData密封无构造、Body无setter的问题,提供以下几种可行的单元测试方案:
1. 官方推荐:通过EventGridEvent构造并转换(优先选择)
新版SDK设计上更推荐围绕EventGridEvent进行事件处理,而非直接实例化特定数据类。你可以先构造包含目标Body的EventGridEvent,再转换为IotHubDeviceTelemetryEventData:
构造测试用事件
// 定义你的Body数据 var testBody = new { Temperature = 28, DeviceId = "test-device-001" }; // 创建EventGridEvent,将Body序列化为BinaryData var testEvent = new EventGridEvent( subject: "devices/b82bfa90fb/gw-uplink", eventType: "Microsoft.Devices.DeviceTelemetry", dataVersion: "1.0", data: BinaryData.FromObjectAsJson(testBody) ); // 转换为IotHubDeviceTelemetryEventData var telemetryData = testEvent.Data.ToObjectFromJson<IotHubDeviceTelemetryEventData>(); // 此时telemetryData.Body即为你传入的testBody对应的BinaryData
在单元测试中,你可以直接将testEvent传入被测试方法,或者转换后使用telemetryData,完全满足测试需求。
2. 修复ParseMany无法识别Body的问题
使用EventGridEvent.ParseMany后,需要显式将Data属性转换为IotHubDeviceTelemetryEventData才能获取Body:
var egEvents = EventGridEvent.ParseMany(BinaryData.FromStream(req.Body)); foreach (var egEvent in egEvents) { if (egEvent.EventType == "Microsoft.Devices.DeviceTelemetry") { var telemetryData = egEvent.Data.ToObjectFromJson<IotHubDeviceTelemetryEventData>(); // 获取Body并转换为目标类型 var body = telemetryData.Body.ToObjectFromJson<YourBodyType>(); // 后续处理逻辑 } }
3. 反射创建实例(不推荐,仅应急)
如果必须直接构造IotHubDeviceTelemetryEventData实例,可以通过反射调用私有构造并设置内部字段,但该方式依赖SDK内部实现,可能随版本更新失效:
using System.Reflection; // 调用私有无参构造 var constructor = typeof(IotHubDeviceTelemetryEventData) .GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null); var telemetryData = (IotHubDeviceTelemetryEventData)constructor.Invoke(null); // 设置内部_body字段 var bodyField = typeof(IotHubDeviceTelemetryEventData) .GetField("_body", BindingFlags.NonPublic | BindingFlags.Instance); bodyField.SetValue(telemetryData, BinaryData.FromObjectAsJson(yourBodyObject));
4. 调整测试依赖,避免Mock密封类
由于IotHubDeviceTelemetryEventData是密封类,Moq等框架无法直接Mock。建议调整测试逻辑:
- 改用实际构造的
EventGridEvent或转换后的IotHubDeviceTelemetryEventData实例作为测试输入 - 如果需要模拟复杂场景,考虑抽象事件处理逻辑,依赖
EventGridEvent而非具体的数据类
内容的提问来源于stack exchange,提问作者macm
相关产品推荐
相关产品推荐

