Visual Studio 2012 ExcludeFromCodeCoverage方法显示在结果中

时间:2012-10-12 13:53:24

标签: c# unit-testing

我有以下方法:

[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")除外,尽管该方法具有属性,但显示为未覆盖。

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

1 个答案:

答案 0 :(得分:8)

我可以解释为什么即使你在类上指定了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。这可能是我的首选。

相关问题