gpt4 book ai didi

java - 单元测试类的最佳实践,主要负责调用依赖项的方法,但也包含逻辑

转载 作者:行者123 更新时间:2023-12-01 12:55:33 24 4
gpt4 key购买 nike

假设我有 StartCommandHandler它有责任创建一些带有所需文件的文件。但是为此,我必须给他一组子职责,例如:

  • 检查 FTP 中是否存在文件
  • If Not 将文件从多个来源下载到临时文件夹
  • 然后执行文件夹
  • 中的一些脚本
  • 然后在脚本执行后读取生成的文件
  • 然后从该文件夹创建 zip
  • 然后删除该文件夹
  • 然后更新数据库

  • 由于该命令处理程序,我们正在创建包含所有必需文件的文件夹。现在该文件夹已准备好进行其他操作。

    我刚刚阅读了 "Art of the Unit testing" .并开始添加单元测试。我关注了 SOLID原则也是如此。特别是, SRPDIP ,在我看来,这是单元测试的先决条件。
    所以,我上面所说的大部分事情都是通过特定的接口(interface)完成的。因此,该命令处理程序 90% 的工作是调用依赖项的方法。而 10% 就是这样的逻辑:
    if(!_dependency1.IsAnySomething())
    {
    _dependency2.Download();

    var isScriptNeeded = _dependency2.IsScriptNeeded();

    if(isScriptNeeded)
    {
    var res = _dependency3.ExecuteScript();
    _dependency4.SetScriptResult(res.Info, res.Date, res.State);
    }

    _dependency3.Archive();

    _dependency5.DeleteTemp();
    }

    我已经测试了该命令处理程序的所有依赖项。但是,帽子命令处理程序还包括一些小逻辑,例如,是否需要下载文件,或者临时文件是否被删除等等......

    我脑子里有很多问题,比如:
  • 可能单元测试对这些单元没有意义?集成测试来拯救?因为,测试是否检查所有调用似乎是错误的,例如是否 DeleteTemp下载后调用,或脚本是否执行,或脚本结果以正确的方式传递SetScriptResult方法。它是好的单元测试吗?
  • 有没有办法重构该类以使其可测试?
  • 最佳答案

    单元测试应该测试代码的行为,而不是代码的实现。

    考虑单元测试如何增加值(value)是有帮助的:它们传达代码的预期行为,并验证预期行为是由实现生成的。它们在您的项目生命周期中增加了两次值(value):第一次是在最初实现代码时,第二次是在重构代码时。

    但是,如果单元测试与特定实现密切相关,则在重构时单元测试无法增加值(value)。

    它从来都不是一门完美的科学,但要知道你是在测试行为还是实现的一种方法是问“如果我重构,这个单元测试会中断吗?”如果重构会破坏测试,那么它就不是一个好的单元测试。

    编写单元测试来简单地确保方法 A 被调用,然后是方法 B,然后是方法 C(或其他)通常是没有帮助的。这只是为了测试你的实现就是你的实现,它可能会阻碍而不是帮助下一个想要重构代码的开发人员。

    相反,请考虑行为以及您的代码如何与其他对象交互。尝试将这些行为中的每一个梳理成单独的对象,并单独测试这些对象。

    例如,您可能会将上述代码分解为三种不同的行为:

  • 一个缓存对象,它检查一个值是否不存在,然后调用一个工厂来创建它,
  • 一个工厂对象,它创建一个空目录,调用一个构建器对象来填充它,然后压缩并删除它
  • 一个构建器对象,它将文件下载到一个目录并运行它在那里找到的脚本。

  • 这些对象中的每一个都有可单独测试的行为:
    class Cache {
    Cache(ValueStore store, ValueFactory factory) { ... }

    object GetValue(object key) {
    if (!store.HasValue(key))
    factory.CreateValue(key);
    return store.GetValue(key);
    }
    }

    class CacheTest {
    void GetValue_CallsFactory_WhenValueNotInStore() {
    // arrange
    var store = Mock.Of<VaueStore>(_ => _.HasValue() == false);
    var factory = Mock.Of<ValueFactory>();
    var cache = new Cache(store, factory);

    // act
    cache.getValue();

    // assert
    Mock.Get(factory).Verify(_ => _.CreateValue(), Times.Once());
    }
    }

    您可以对工厂和 builder 进行类似的分解,并分别测试他们的行为。

    关于java - 单元测试类的最佳实践,主要负责调用依赖项的方法,但也包含逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61848902/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com