【问题标题】:Code Coverage on Lambda ExpressionsLambda 表达式的代码覆盖率
【发布时间】:2010-09-13 14:32:49
【问题描述】:

我在整个代码中看到一个模式,其中 lambda 表达式显示为代码覆盖范围内未覆盖,调试器会逐步执行代码并且没有条件块。

public CollectionModel()
{
    List<Language> languages = LanguageService.GetLanguages();
    this.LanguageListItems =
        languages.Select(
            s =>
            new SelectListItem { Text = s.Name, Value = s.LanguageCode, Selected = false }). // <-- this shows as not covered
            AsEnumerable();
}

这有点奇怪。有什么想法吗?

【问题讨论】:

    标签: c# unit-testing lambda code-coverage


    【解决方案1】:

    我认为您的意思是调试器没有越过指示的行;是这样吗?

    如果这是您的问题,那么答案是,至少在这种特殊情况下,您看到的是延迟执行System.Linq.Enumerable 提供的所有 LINQ 扩展方法都表现出这种行为:即 lambda 语句本身内的代码在您定义它的行上执行。仅在枚举结果对象后才执行代码。

    在您发布的代码下方添加:

    foreach (var x in this.LanguageListItems)
    {
        var local = x;
    }
    

    在这里,您将看到调试器跳回您的 lambda。

    【讨论】:

    • +1。或者,他也可以使用ToList 而不是AsEnumerable 并具有相同的效果。
    • @nikie:是的,但我特别希望他看到调试器在迭代时跳回 lambda,因为我觉得这可以清楚地清楚发生了什么。
    • 还要注意,如果集合是空的,那么即使集合被迭代,投影也永远不会被调用。
    • 调试器会逐步执行此操作。这就是为什么它如此令人困惑。出于某种原因,我的公司希望我们使用 AsEnuerable 而不是 list。
    • 你们是绝对正确的。使用 ToList() 枚举代码时,代码会正确执行
    【解决方案2】:

    当你进行单元测试时,如果你有一个方法可以返回你描述为 LanguageListItems 的列表,你可以在单元测试中这样做:

    var result = await controller.SomeAction();
    var okObjectResult = Assert.IsType<OkObjectResult>(result);
    var results = Assert.IsAssignableFrom<IEnumerable<YourDtoClass>>okObjectResult.Value);
    Assert.NotNull(results);
    Assert.All(results, dto => Assert.NotNull(dto.PendingItemCount));
    Assert.All(results, dto => Assert.NotNull(dto.ApprovedItemCount));
    

    任何 dto 属性的每个 Assert 都会执行 lambda 表达式,然后它会显示为已覆盖。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-25
      • 2012-06-30
      • 2018-01-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多