如何通过ArchUnit禁止调用System.String.Substring()?测试未生效求助
用ArchUnit检测直接调用String.Substring()的问题排查
需求背景
- 已封装
Lib.Utility.SubString()方法,内部调用string.Substring(),作为统一的字符串截取入口 - 要求
Prg控制台项目中仅允许调用封装方法,禁止直接调用字符串实例的Substring()方法 - 编写的MS单元测试未触发预期失败,需排查问题
相关代码
Lib库代码
namespace Lib { public static class Utility { public static string SubString(string input, int position) { return input.Substring(position); } } }
Prg项目代码
namespace Prg { internal class Program { static void Main(string[] args) { // 允许的调用 Console.WriteLine(Lib.Utility.SubString("Hello World", 6)); // 应被检测的调用 Console.WriteLine("Hello World".Substring(6)); Console.ReadKey(); } } }
原单元测试代码
using ArchUnitNET.Domain; using ArchUnitNET.Loader; using static ArchUnitNET.Fluent.ArchRuleDefinition; namespace LibTest { [TestClass] public class PrgTest { private static readonly Architecture Architecture = new ArchLoader().LoadAssemblies(System.Reflection.Assembly.Load("Prg")).Build(); [TestMethod] public void TestIndexOf() { var classesThatCallStringDotSubString = Classes().That().CallAny("System.String.Substring").Should().NotExist(); var result = classesThatCallStringDotSubString.Evaluate(Architecture).ToList(); Assert.IsTrue(result[0].Passed); } } }
问题排查与解决
1. 规则匹配精度不足
原测试中CallAny("System.String.Substring")无法精准匹配字符串实例的Substring调用。ArchUnit对方法调用的匹配需要更精确的条件,尤其是要区分实例方法和静态方法。
2. 断言逻辑错误
原测试断言Assert.IsTrue(result[0].Passed),而规则定义为Should().NotExist()——当Prg中存在违规调用时,规则的Passed属性会是false,此时断言true会导致测试“假通过”,与预期检测违规的需求相悖。
修正后的单元测试代码
using ArchUnitNET.Domain; using ArchUnitNET.Loader; using static ArchUnitNET.Fluent.ArchRuleDefinition; using System; namespace LibTest { [TestClass] public class PrgTest { private static readonly Architecture Architecture = new ArchLoader() .LoadAssemblies(System.Reflection.Assembly.Load("Prg")) .Build(); [TestMethod] public void TestDirectStringSubstringCalls() { // 定义规则:Prg程序集中的类不能调用System.String的实例方法Substring var directSubstringCallRule = Classes() .That().ResideInAssembly("Prg") .Should().NotCallMethodWhere(method => method.DeclaringType.FullName == "System.String" && method.Name == "Substring" && !method.IsStatic); // 执行规则检查 var evaluationResult = directSubstringCallRule.Evaluate(Architecture); // 断言规则未通过(即存在违规调用) Assert.IsFalse(evaluationResult.Passed, "检测到直接调用System.String.Substring()的违规代码"); } } }
关键优化点
- 增加
ResideInAssembly("Prg")缩小检查范围,避免误判其他程序集的合法调用 - 使用
CallMethodWhere通过方法声明类型、名称、是否静态的组合条件,精准匹配字符串实例的Substring调用
内容的提问来源于stack exchange,提问作者TorstenM
相关产品推荐
相关产品推荐

