如何模拟FeatureFilterEvaluationContext参数?自定义筛选器测试属性为空
问题解决:Azure Feature Manager自定义筛选器单元测试中Settings属性绑定失败
问题原因
你在单元测试中使用AddInMemoryCollection存入的是序列化后的JSON字符串,但.NET配置系统的Get<T>方法默认通过层级键值对(如AllowedIds:0)来绑定数组/复杂对象,无法自动将JSON字符串反序列化为数组属性,导致AllowedIds和BlockedIds为null。而实际运行时,Azure Feature Manager的配置来源(如App Settings)会以正确的层级结构被解析,所以能正常绑定。
解决方案
方案1:使用配置层级格式构建参数
直接用配置系统识别的数组键格式存入参数,这是最贴合真实配置场景的方式:
var parameters = new Dictionary<string, string?> { { "AllowedIds:0", "someId1" }, { "AllowedIds:1", "someId2" }, { "BlockedIds:0", "someId3" } }; var context = new FeatureFilterEvaluationContext { Parameters = new ConfigurationBuilder().AddInMemoryCollection(parameters).Build() };
这种格式下,context.Parameters.Get<IdFilterSettings>()会自动将AllowedIds:0、AllowedIds:1绑定为数组元素,正确填充属性值。
方案2:模拟JSON配置源
如果需要模拟真实环境中的JSON配置格式,可以用AddJsonStream来构建配置:
// 构建要绑定的Settings对象 var testSettings = new IdFilterSettings { AllowedIds = new[] { "someId1", "someId2" }, BlockedIds = new[] { "someId3" } }; // 序列化为JSON并转为流 var jsonBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(testSettings)); var jsonStream = new MemoryStream(jsonBytes); // 用JSON流构建配置 var config = new ConfigurationBuilder() .AddJsonStream(jsonStream) .Build(); var context = new FeatureFilterEvaluationContext { Parameters = config };
这种方式和真实环境中从JSON配置文件读取的逻辑一致,Get<IdFilterSettings>能正确解析所有属性。
方案3:手动解析参数(不推荐,仅临时调试用)
如果不想修改测试的参数构建方式,可以在筛选器的EvaluateAsync方法中手动解析JSON字符串:
public virtual Task<bool> EvaluateAsync(FeatureFilterEvaluationContext context) { var allowedIdsJson = context.Parameters["AllowedIds"]; var blockedIdsJson = context.Parameters["BlockedIds"]; _settings = new IdFilterSettings { AllowedIds = string.IsNullOrEmpty(allowedIdsJson) ? null : JsonSerializer.Deserialize<string[]>(allowedIdsJson), BlockedIds = string.IsNullOrEmpty(blockedIdsJson) ? null : JsonSerializer.Deserialize<string[]>(blockedIdsJson) }; // 剩余逻辑... }
注意:这个方法会破坏和真实运行时代码的一致性,仅建议用于临时调试,优先使用前两种方案。
内容的提问来源于stack exchange,提问作者ScubaSteve
相关产品推荐
相关产品推荐

