4

我有以下方法:

[ExcludeFromCodeCoverage]
private static string GetAuthorizationToken(HttpActionContext actionContext)
{
    var authorization = actionContext.Request.Headers.FirstOrDefault(h => h.Key.Equals("Authorization"));
    // ... removed for brevity
}

ExcludeFromCodeCoverage属性适用于整个方法,除了h.Key.Equals("Authorization"),尽管方法上有属性,但它显示为未覆盖。

如何从代码覆盖结果中排除此符号?

4

1 回答 1

9

我可以解释为什么即使您在类上指定了 ExcludeFromCodeCoverage 属性,它仍显示为未被覆盖。解释在于编译器实际生成的 IL。它声明了一个委托来匹配看起来像这样的 lambda 表达式。

private static Func<string, bool> AnonymousMethodDelegate;

然后它创建与委托声明匹配的命名方法。

[CompilerGenerated]
private static bool CompilerGeneratedMethod(string h)
{
  return h.Equals("Authorization");
}

然后最后是使用方法中的委托调用命名方法,如下所示

[ExcludeFromCodeCoverage]
private static string GetAuthorizationToken(HttpActionContext actionContext)
{
  AnonymousMethodDelegate = CompilerGeneratedMethod;
  Func<string, bool> predicate = AnonymousMethodDelegate;
  return Enumerable.FirstOrDefault<string>((IEnumerable<string>) actionContext, predicate);
}

我相信你已经发现了问题。编译器创建了一个不再附加 ExcludeFromCodeCoverage 属性的方法!这就是 NCover 判断它没有被覆盖的原因,即使您似乎已经声明了 ExcludeFromCodeCoverage 属性。

排除它的一种方法是回到基础并有效地执行编译器为您执行的操作并声明委托和命名方法。这使您能够将 ExcludeFromCodeCoverage 属性添加到该命名方法。尽管出于明显的原因,我不是这个解决方案的忠实粉丝。

显然,如果您在类级别添加 ExcludeFromCodeCoverage 属性,它还将涵盖此生成的方法,这将解决此问题,但我认为这也会排除您想要包含在覆盖率报告中的代码。

另一种选择是,如果您使用的是 NCover,那么您可以使用所有编译器生成的方法都使用 CompilerGenerated 属性修饰的事实。您可以将要排除的属性传递给 NCover,因此您所要做的就是在命令行或通过 MSBuild 任务传递 System.Runtime.CompilerServices.CompilerGeneratedAttribute。这可能是我的首选。

于 2012-11-02T00:02:24.650 回答