如何对自己的自定义分析器和代码修复提供程序进行单元测试?
我正坐在电脑前,手放在键盘上,但我不知道要输入什么。
最佳答案
一个很好的起点是使用“诊断和代码修复”模板创建一个新的解决方案。这将创建一个带有几个类的单元测试项目,使您可以非常轻松地测试诊断程序。
但是,这也显示了它的弱点:这些类在您的代码库中进行了硬编码,并且不是可以在需要时轻松更新的依赖项。在像Roslyn这样仍在不断变化的代码库中,这意味着您将很快落后:测试类针对Beta-1,而在撰写本文时,Roslyn已经针对RC2。
我提出了两种解决方案:
这个主意
助手的想法很简单:给定一个或多个代表类文件的字符串和一个或多个代表预期诊断结果的对象,使用给定的类创建一个内存中项目并执行分析器。
对于CodeFix提供程序,您还可以指定代码在转换后的外观。
执行
怎么称呼呢?
这是一个示例测试,当您使用名称不以“Async”结尾的异步方法并提供CodeFix来更改名称时,该示例将显示警告。
[TestMethod]
public void AsyncMethodWithoutAsyncSuffixAnalyzer_WithAsyncKeywordAndNoSuffix_InvokesWarning()
{
var original = @"
using System;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class MyClass
{
async Task Method()
{
}
}
}";
var result = @"
using System;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class MyClass
{
async Task MethodAsync()
{
}
}
}";
var expectedDiagnostic = new DiagnosticResult
{
Id = AsyncMethodWithoutAsyncSuffixAnalyzer.DiagnosticId,
Message = string.Format(AsyncMethodWithoutAsyncSuffixAnalyzer.Message, "Method"),
Severity = EmptyArgumentExceptionAnalyzer.Severity,
Locations =
new[]
{
new DiagnosticResultLocation("Test0.cs", 10, 13)
}
};
VerifyCSharpDiagnostic(original, expectedDiagnostic);
VerifyCSharpFix(original, result);
}
如您所见,设置非常简单:确定错误代码的外观,指定错误代码的外观,并指出应显示的警告的属性。
创建项目
第一步是创建内存项目。这包括几个步骤:
new AdhocWorkspace()
).CurrentSolution.AddProject()
).AddMetadataReferences()
)solution.AddDocument()
)收集诊断
在这里,我们将使用刚刚创建的文档。这两行最重要:
var compilation = project.GetCompilationAsync().Result;
var diagnostics = compilation.WithAnalyzers(ImmutableArray.Create(analyzer))
.GetAnalyzerDiagnosticsAsync()
.Result;
验证诊断
至此,您已经拥有了所需的一切:您获得了实际结果,并且获得了预期的结果。剩下的就是验证两个集合是否匹配。
应用代码修复
这大致遵循与诊断相同的模式,但又增加了一点点。
CodeFixContext
var actions = new List<CodeAction>();
var context = new CodeFixContext(document, analyzerDiagnostics[0],
(a, d) => actions.Add(a), CancellationToken.None);
codeFixProvider.RegisterCodeFixesAsync(context).Wait();
var operations = codeAction.GetOperationsAsync(CancellationToken.None).Result;
var solution = operations.OfType<ApplyChangesOperation>().Single().ChangedSolution;
如果一切仍然有些模糊,请绝对看看the exact source code。如果您想获得有关如何创建自己的诊断程序的更清晰示例,请查看my VSDiagnostics repository或my blogpost on writing your own。
关于c# - 如何对罗斯林诊断程序进行单元测试?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30384868/