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

使用Roslyn解析布尔表达式遇CS0103错误,求解决集成测试JSON断言问题

解决Roslyn解析断言字符串时的"entry不存在"错误

我完全懂你碰到的问题——你想用Roslyn执行JSON测试用例里的断言表达式,但脚本引擎压根不知道entry是什么,因为你没把这个测试对象注入到脚本的上下文环境里,所以才抛出了CS0103这个错误。咱们一步步来搞定它:

1. 先搞清楚问题根源

结合你提到的JSON结构,你的测试用例大概是这样的:

{
  "entries": [
    {
      "name": "商品价格验证",
      "assertion": "entry.Price > 99",
      "Price": 129
    }
  ]
}

当你直接拿entry.Price > 99这个字符串给Roslyn执行时,脚本环境里没有任何叫entry的变量,自然会报错说“名称不存在”。

2. 核心解决方案:给Roslyn注入entry变量

你需要在执行脚本前,把当前测试用例的entry对象传递到Roslyn的脚本上下文里。下面是具体的C#代码示例:

第一步:先把JSON结构映射成C#实体类

先定义和JSON对应的类,方便后续处理测试数据:

public class TestEntry
{
    public string Name { get; set; }
    public string Assertion { get; set; }
    // 根据你的JSON字段添加对应属性,比如价格、ID等
    public int Price { get; set; }
}

第二步:用Roslyn执行断言并传入entry

通过ScriptOptions配置必要的程序集引用,再用全局上下文把entry对象传给脚本:

using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System.Text.Json;

// 从JSON文件加载测试用例(这里用示例数据代替文件读取)
var jsonContent = @"{""entries"": [{""name"":""商品价格验证"",""assertion"":""entry.Price > 99"",""Price"":129}]}";
var testCase = JsonSerializer.Deserialize<TestCase>(jsonContent);

foreach (var entry in testCase.entries)
{
    try
    {
        // 配置脚本选项:添加当前程序集引用(因为TestEntry在当前项目里)、导入命名空间
        var scriptOptions = ScriptOptions.Default
            .AddReferences(typeof(TestEntry).Assembly)
            .AddImports(typeof(TestEntry).Namespace);

        // 用匿名类型作为全局上下文,把当前entry对象传进去
        var globals = new { entry = entry };

        // 执行断言脚本,获取布尔结果
        bool assertionResult = await CSharpScript.EvaluateAsync<bool>(entry.Assertion, scriptOptions, globals);

        Console.WriteLine($"测试用例「{entry.Name}」结果:{(assertionResult ? "通过" : "失败")}");
    }
    catch (CompilationErrorException ex)
    {
        Console.WriteLine($"测试用例「{entry.Name}」编译错误:\n{string.Join("\n", ex.Diagnostics)}");
    }
}

// 对应JSON的根类
public class TestCase
{
    public List<TestEntry> entries { get; set; }
}

3. 几个关键注意事项

  • 全局上下文的作用:这里的匿名类型new { entry = entry }是给Roslyn脚本提供全局变量的容器,脚本里的entry会直接映射到这个容器的entry属性,这样脚本就知道它指代的是哪个测试对象了。
  • 程序集和命名空间:必须添加包含TestEntry的程序集引用和对应命名空间,否则脚本会识别不了TestEntry的类型。
  • 异步处理:EvaluateAsync是异步方法,生产环境里尽量用await,如果是控制台测试可以用.Result但不推荐。

4. 扩展:处理复杂断言场景

如果你的断言需要用到DateTime、LINQ或者其他系统类型,只需要在ScriptOptions里添加对应的引用和命名空间就行:

var scriptOptions = ScriptOptions.Default
    .AddReferences(typeof(TestEntry).Assembly, typeof(DateTime).Assembly, typeof(Enumerable).Assembly)
    .AddImports(typeof(TestEntry).Namespace, "System", "System.Linq");

这样就能解决entry不存在的问题,顺利把JSON里的断言字符串解析成布尔结果啦!

内容的提问来源于stack exchange,提问作者Emiliano Montesdeoca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:42:38