触摸数据库的配置工具上的TDD

时间:2014-10-27 04:54:24

标签: c# tdd

我正在写一个工具 - 建立与Sql的连接并运行一系列存储过程 - 命中文件系统以验证并删除文件 - 通过公开的API与其他子系统进行交流

我对TDD的概念不熟悉,但一直在做很多阅读。我想在这个开发中应用TDD,但我被卡住了。与外部系统有很多交互需要被模拟/存根或伪造。我发现困难的是在TDD中采用这种方法的正确方法。这里是我想要完成的一个示例。

public class MyConfigurator
{
    public static void Start()
    {
        CheckSystemIsLicenced(); // will throw if its not licenced. Makes call to a library owned by company

        CleanUpFiles(); // clean up several directories

        CheckConnectionToSql(); //ensure connection to sql can be made

        ConfigureSystemToolsOnDatabase(); //runs a set of stored procedure. Range of checks are also implemented and will throw if something goes wrong.
    }
}

在此之后,我有另一个课程,如果出现问题,我们会清理系统。出于这个问题的目的,它不是那么相关,但它本质上只是清除某些表并修复数据库,以便该工具可以从头开始重新运行以完成其配置任务。

在使用TDD时,我似乎最终只有这样的测试(假设我使用的是FakeItEasy)

A.CallTo(()=>fakeLicenceChecker.CheckSystemIsLicenced("lickey")).MustHaveHappened();

这只是一大堆测试,似乎是#34; MustHaveHappened"。难道我做错了什么?有没有不同的方法来使用TDD启动这个项目?或者这是一个特殊情况,也许不推荐TDD?任何指导都将不胜感激。

3 个答案:

答案 0 :(得分:1)

在这个特定方法中,您唯一可以测试的是调用方法。通过断言模拟类来做你正在做的事情是可以的。由您决定此特定测试是否有价值取决于您。 TDD假设测试一切,但我发现将测试集中在增加价值的场景上更为实际。其他人很难做出这样的决定,但你应该相信自己能够在每个特定情况下进行调用。

答案 1 :(得分:1)

我认为集成测试会增加最大的收益。使用真正的数据库和文件系统。

如果工具中有复杂的逻辑,那么您可能需要重新构建工具设计以抽象出DB和fileSystem并使用模拟编写单元测试。从你发布的代码片段来看,它看起来像是一个简单的脚本。

答案 2 :(得分:1)

在您的示例中,如果单元测试的排列显示lickey作为输入,则断言已使用适当的值调用端点是合理的。在更复杂的场景中,输入到断言流程涵盖了更多子系统,因此测试本身看起来并不简单。您可以将ID值设置为输入,并测试您输出的值是否与输入ID确定性相关的对象的值。

TDD的一个方面是代码在测试时没有变化 - 除了功能等同的重构。因此,您的第一个测试自然会在最外端点排列和断言数据。您将从一个将实际文件写入文件系统的测试开始,调用您的代码,然后检查该文件是否按预期删除。当然,文件系统对于便携式测试来说是一个混乱的工作空间,因此您可能会尽早决定将文件系统抽象一步。通过使用EF和模拟DbContext或使用模拟的存储库模式与数据库同上。这些抽象可以是TDD前应用程序架构决策。

我经常做的事情是使用以IFileSystem接口开头的实用程序代码,该接口声明模仿System.IO.File中许多可用内容的方法。在生产中,我使用IFileSystem的实现,它只是传递给File.XXX()方法。然后,您可以模拟并验证界面,而不是尝试设置和清理真实文件。