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

C# Roslyn源代码生成器运行正常但单元测试无法生成预期代码

Roslyn源代码生成器测试异常问题

问题背景

开发的简单Roslyn增量源代码生成器在实际项目中可正常生成代码,但编写的单元测试无法触发预期的代码生成逻辑,表现为谓词返回true却未进入transform环节。

生成器代码

using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System.Text;

namespace TestGenerator;

[Generator]
public class TestGenerator : IIncrementalGenerator
{
    public void Initialize(IncrementalGeneratorInitializationContext context)
    {
        var classDeclarations = context.SyntaxProvider.ForAttributeWithMetadataName(
                "TestGenerator.TestSourceGeneratorAttribute",
                predicate: static (s, _) => (s is ClassDeclarationSyntax || s is StructDeclarationSyntax) && s is TypeDeclarationSyntax type && type.Modifiers.Any(SyntaxKind.PartialKeyword),
                transform: static (ctx, _) =>
                {
                    if (ctx.TargetNode is TypeDeclarationSyntax typeDeclarationSyntax)
                    {
                        return typeDeclarationSyntax.Identifier.ToString();
                    }
                    return null;
                })
            .Where(static m => m is not null);
        var compilationAndClasses = classDeclarations.Collect();

        context.RegisterSourceOutput(compilationAndClasses, static (spc, classes) =>
        {
            foreach (var typeDefinition in classes)
            {
                spc.AddSource($"{typeDefinition}.g.cs",
                    SourceText.From(GetSource(typeDefinition), Encoding.UTF8));
            }
        });
    }

    private static string GetSource(string source)
    {
        return $@"
            //<auto-generated/>
            #nullable enable
            using System;
            
            /// {source}
            ";
    }
}

项目内正常运行示例

项目中添加测试类:

namespace TestGenerator.Test
{
    [TestSourceGenerator]
    public partial class TestClassGenerated
    {
    }
}

可正常生成代码:

//<auto-generated/>
#nullable enable
using System;

/// TestClassGenerated

单元测试代码

using Microsoft.CodeAnalysis.CSharp.Testing;
using Microsoft.CodeAnalysis.Testing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Threading.Tasks;

namespace TestGenerator.Test;

[TestClass]
public class TestGeneratorUnitTest
{
    [TestMethod]
    public async Task Test123()
    {
        var source = @"
            using System;

            namespace TestGenerator.Test
            {
                [TestSourceGenerator]
                public partial class MyClass
                {
                }
            }
            ";

        var expectedGeneratedCode = @"
                //<auto-generated/>
                #nullable enable
                using System;

                /// MyClass
                ";

        var test = new CSharpSourceGeneratorTest<TestGenerator, DefaultVerifier>
        {
            TestState =
            {
                Sources = { source },
                GeneratedSources =
                {
                    (typeof(TestGenerator), "MyClass.g.cs", expectedGeneratedCode)
                }
            }
        };

        await test.RunAsync();
    }
}

问题原因

测试代码的source仅引用了[TestSourceGenerator]属性,但未在测试的编译环境中提供该属性的定义。ForAttributeWithMetadataName依赖元数据匹配属性,测试环境无法找到对应属性的元数据,导致即使语法层面匹配(谓词返回true),也无法进入transform阶段。

解决方案

  1. 在测试的source中添加TestSourceGeneratorAttribute的完整定义,确保测试编译环境能识别该属性:
var source = @"
    using System;

    namespace TestGenerator
    {
        [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = false, AllowMultiple = false)]
        sealed class TestSourceGeneratorAttribute : Attribute
        {
        }
    }

    namespace TestGenerator.Test
    {
        [TestSourceGenerator]
        public partial class MyClass
        {
        }
    }
    ";
  1. 调整预期代码的格式,确保与生成器输出完全一致(避免缩进、换行差异导致测试失败):
var expectedGeneratedCode = @"
//<auto-generated/>
#nullable enable
using System;

/// MyClass
";

内容的提问来源于stack exchange,提问作者Luiz Bicalho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:24:56