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

如何通过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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 11:16:18