代码之家  ›  专栏  ›  技术社区  ›  STW

.NET单元测试-在发布代码中隐藏测试接缝的最佳实践

  •  5
  • STW  · 技术社区  · 16 年前

    全部

    [InternalAttributesVisibleTo("MethodLogger.Tests")]
    internal static class MethodLogger
    {
        public void WriteEntry(string message)
        {
            LogWriter.WriteEntry(message);
        }
    
        private IMethodLogger LogWriter
        {
            get;
            set;
        }
    
    #if DEBUG
        internal void SetLogWriter(IMethodLogger logger)
        {
            LogWriter = logger;
        }
    #endif
    }
    

      • 我是否希望对非调试版本运行单元测试?从我的头脑中,我看到的价值不多了——但会有吗?
    11 回复  |  直到 16 年前
        1
  •  4
  •   RoyOsherove    16 年前

    您可以使用Typemock Isolator来规避任何损害可测试性的设计问题。

    http://blog.typemock.com/2009/01/isolator-new-vbnet-friendly-api.html

        2
  •  3
  •   Jon Skeet    16 年前

    你能不能把设置器标记为“过时”,并在测试代码中禁用过时的警告?连同适当的文档,这应该可以防止生产代码意外调用它,但仍然可以用于测试。

    • 是的,如果你愿意,你可以使用你自己的预处理器符号(如TEST);您可以将其应用于现有配置,也可以创建新的构建配置。
        3
  •  3
  •   Lou Franco    16 年前

    混淆使内部完全无法使用,这对我来说已经足够好了,所以我们留在测试方法中(并将其内部化)。

        4
  •  3
  •   Mark Seemann    16 年前

    事实上,你正在走向依赖注入的道路上——你只是还没有意识到:)

    将接缝留在原位并没有什么错——你只需要对它们进行建模,这样它们就不会是特定于测试的,而是实际上 增强

    Testability Is Really The Open/Closed Principle .

    在您的特定情况下,您应该对MethodLogger类进行一些更改:

    1. 将其设置为实例类而不是静态类。正如所有经验丰富的TDD实践者都会告诉你的那样,静态是 邪恶 .
    2. 构造函数采用IMethodLogger的实例。这叫做 构造器注入 并强制所有客户端明确决定如何登录。
        5
  •  2
  •   Finglas    16 年前

    #IF DEBUG 等等……是不好的形式。

    生产代码应独立于测试/调试代码。

    我建议研究依赖注入来帮助单元测试。

        6
  •  2
  •   azheglov    16 年前
    1. 正如其他人所说,转向依赖注入和控制反转(IoC)
    2. 将测试移动到单独的程序集中-不需要#if DEBUG。..#endif
        7
  •  2
  •   Gavin Chin    16 年前

    根据Michael Feathers的《有效使用遗留代码》一书,如果你为设置器命名一些特定的测试名称,似乎会更好。

    例子: SetTestingLogger(IMethodLogger记录器)

    我还将删除预处理器语句。这本书还指出,我引用

    “你可能会有点不舒服 您正在删除访问权限的想法 使用静态设置器时的保护, 错误。我们正在进行测试 还可以防止错误。"

    结论: 似乎最好把这些钩子放进去,因为你放置它是为了测试,并最终消除错误。

    本书中的“介绍静态设置器”部分对此进行了更详细的解释。我会推荐这本书作为每个开发人员都应该拥有的书。

        8
  •  1
  •   Matt Briggs    16 年前

    在我看来,这似乎是IoC容器的主要候选者。我会让我的记录器不是静态的,并为测试、开发和生产设置不同的配置。

        9
  •  1
  •   cfeduke    16 年前

    Log4Net

    StructureMap ,在运行时根据各种配置分配混凝土。在单元测试期间,您可以使用以下库 Moq 制造以预期方式运行的混凝土(总是返回相同确切结果的SQL查询),尽管在您的特定情况下,您执行的是相反的操作(在单元测试期间进行所需的日志记录,而在生产运行时不进行日志记录)。

        10
  •  1
  •   Randolpho    16 年前

    这是一种内部方法。只需保持原样,不进行条件编译,只需 呼叫

    保留钩子并没有什么错——事实上,你甚至可能想考虑制作这个方法 并允许任何代码更改日志挂钩。

    再次查看您的代码;你甚至都不知道 需要

    我可以看到保留钩子是可以的,删除它只是一种偏好,但我不同意将其公开——这感觉太像是仅仅因为它消除了一点麻烦就提高了权限。 Yoooder

        11
  •  0
  •   Adam Hughes    16 年前

    我是否可以使用 自定义预编译器标志,如“TEST” 关于告诉Visual Studio始终 使用此标志重建目标 测试以确保我的钩子/接缝

    对。您要做的是添加一个条件编译符号。您可以在“构建”选项卡下的项目属性中执行此操作。您可以在配置管理器中创建不同的构建配置,并仅将您的TEST符号添加到新配置中。