在单元测试中使用SpringRunner可以吗?

2024-04-27

我们正在与我的同事争论这种方法。他们说仅在集成或功能级别上使用 SpringRunner。

问题是在下面的级别中使用它有什么优点和缺点?

例如我有简单的豆:

public class RewardDurationCalculator {

    private Clock clock;

    public OptionalLong calculate(DurationType durationType, List<Pass> passes) {
        long now = Instant.now(clock).getEpochSecond();
        switch (durationType) {
            case FULL_PASS:
                return getCurrentPassDuration(passes, now);
            case TILL_THE_END_OF_THE_CURRENT_ACTIVE_PASS:
                return getTimeInCurrentPassLeft(passes, now);
        }
        return OptionalLong.empty();
    }

    private OptionalLong getCurrentPassDuration(List<Pass> passes, long now) {
        return passes.stream()
                .filter(currentPass(now))
                .mapToLong(Pass::getDuration)
                .findFirst();
    }

    private OptionalLong getTimeInCurrentPassLeft(List<Pass> passes, long now) {
        return passes.stream()
                .filter(currentPass(now))
                .mapToLong(pass -> getEndTs(pass) - now)
                .findFirst();
    }

    private Predicate<Pass> currentPass(long now) {
        return pass -> pass.getStartTs() >= now && now <= getEndTs(pass);
    }

    private long getEndTs(Pass pass) {
        return pass.getStartTs() + pass.getDuration();
    }

}

也就是做一些计算逻辑。为此我还有 spring 配置:

@Configuration
public class RewardDurationCalculatorConfiguration {

    @Bean
    public RewardDurationCalculator rewardDurationCalculator(Clock clock) {
        return new RewardDurationCalculator(clock);
    }

}

那么为什么我不能像这样编写单元测试:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = RewardDurationCalculatorConfiguration.class)
public class RewardDurationCalculatorTest {

    @MockBean
    private Clock clock;
    @Autowired
    private RewardDurationCalculator rewardDurationCalculator;

    @Test
    public void testCalculateCurrentPassDurationShouldBeReturnedIfPassWasCreatedRightNow() {
        rewardDurationCalculator.calculate(DurationType.FULL_PASS, Collections.emptyList());
    }

}

使用这种方法我会面临哪些缺点?


我倾向于同意你同事的观点。

单元测试应该只测试小的代码单元,通常是单个类。他们应该只运行被测试的单元,而不执行该单元的依赖项中的任何代码。

原因之一是单元测试应该尽可能快地执行。在测试驱动开发 (TDD) 中,您通常希望能够在进行每一个小的更改后运行该套件,或者至少是其中的一个相关子集,以验证您没有破坏任何现有行为。仅当测试反馈是即时的时这才可行。如果您必须等待测试结果太长时间,您将减少运行它们的频率,这意味着反馈循环会变得更长。

在较小的 Spring 项目中,Spring 上下文加载速度非常快,因此您可能认为没有太大差异,但如果您经常运行测试,即使是短暂的延迟也会增加。在大型和较旧的代码库中,可能需要一段时间才能启动 Spring 上下文,并且在某些时候它会变得非常慢,以至于您不想每天多次运行整个测试套件,这会极大地损害您的能力练习 TDD。

坚持测试小代码单元的另一个方面是,它迫使您将代码构建为高度解耦(即可测试)的单元。如果您无法为仅测试该类而不测试其他类的类编写单元测试,则可能暗示有机会改进代码的设计。

总而言之,当您启动整个 Spring 上下文进行测试时,根据这个定义,它不再是单元测试,而是集成测试,因为您还在测试整个 Spring 配置、引导、自动装配等,即。 e.将您的类集成到 Spring 应用程序中。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在单元测试中使用SpringRunner可以吗? 的相关文章

随机推荐

  • matplotlib 中的自定义对数轴缩放

    我正在尝试使用 math log 1 x 来缩放绘图的 x 轴 而不是通常的 log 缩放选项 并且我已经查看了一些自定义缩放示例 但我无法得到我的上班 这是我的 MWE import matplotlib pyplot as plt im
  • 升级到 NHibernate 3.1 时 NHibernate 映射中断

    我最近刚刚升级到 FluentNHibernate 1 2 它使用 NHibernate 3 1 升级后 我的一些旧映射无法正常工作 我一直很难弄清楚为什么 我想也许这里有人可以提供帮助 我有 3 个课程 练习 练习和练习练习 一个练习可以
  • Java用Rhino调用JS(未定义Uint8Array)

    我正在尝试使用 Rhino 库从 java 代码调用一些 javascript 但它似乎对类型化数组感到窒息 这是我的简单js文件 function decrypt version iv encryptedBuffer var output
  • 如何将png二进制数据放入img标签中并将其显示为图像?

    我正在用这个 ajax type GET url template bump1 purse png datatype image png success function data var reader new FileReader rea
  • 使用 bitbake 为 BBB 构建 .dtbo 覆盖

    我使用内核 linux ti staging 4 14 和自定义设备树为我的 BBB 构建了 yocto 发行版 rocko 由于我需要将一个旧项目从 Debian 移植到 Yocto 因此我还需要在内核中启用 UIO 功能 这也可以正常工
  • Eclipse XSD 编辑器

    如何启动或安装 Eclipse XSD 编辑器 根据this http wiki eclipse org index php Introduction to the XSD Editor看来它应该开箱即用 我创建了XMLExamples项目
  • Python Mysql 连接器未获取新内容

    我制作了一个简单的 python 脚本 它每 x 秒检查一次 mysql 表并将结果打印到控制台 我使用 MySQL 连接器驱动程序 但是 运行脚本仅打印初始值 我的意思是 如果我在脚本运行时更改数据库中的值 脚本不会注册它 并且它会继续写
  • Google Cloud SQL:SQLSTATE [HY000] [2013]在“读取初始通信数据包”时丢失与 MySQL 服务器的连接,系统错误:0

    自从我的 Google Cloud SQL 实例宕机后 我感到绝望 我昨天可以毫无问题地连接到它 但从今天早上开始我无法以任何方式连接到它 它会产生以下错误 数据库服务器返回此错误 SQLSTATE HY000 2013 在 读取初始通信数
  • Pygame 让对象追逐光标

    过去几个小时一直在做这个 试图制作一个小程序 其中图像追逐光标 到目前为止 我已经设法使图像直接位于光标上方并沿着该方向移动 然而 我需要的是图像真正 追逐 光标 因此它需要最初远离光标 然后在它后面运行 直到它位于鼠标之上 基本上 我遇到
  • Applescript:修剪空格和回车线

    我编写了一个 AppleScript 它从用逗号分隔的文本文件中返回一个随机字符串 set some file to Macintosh HD Users Zade Library Application Support Notationa
  • 如何禁用 yii2 ActiveFrom dropDownList 中的一项?

    Yii2 活跃形式 我想禁用选项2 gt 2 有办法做到吗 您可以使用 选项 键为下拉列表中的所有项目添加属性 假设您想禁用第二项 在文档中 http www yiiframework com doc 2 0 yii helpers bas
  • “没有为 JavaScript 文件指定有效规则”是什么意思?

    我有一个使用以下命令创建的 React Typescript create react app my app scripts version react scripts ts 它编译得很好 但每次我看到此消息或警告时 No valid ru
  • 如何通过单击 Android 中的 ImageView 从一个片段移动到另一个片段?

    我有一个图像视图 我想通过单击 Imageview 从一个片段移动到另一个片段 就像我们可以使用从一个活动移动到另一个活动一样 Intent i new Intent MainActivity this SecondActivity cla
  • 使用 CoreMotion 在后台获取加速度计数据

    尽管这个问题的解决方案看似正确 但我无法在后台接收加速度计数据iPhone 上的 Nike GPS 如何在后台接收加速度计更新 https stackoverflow com questions 8716466 how nike gps o
  • Python 集合上的迭代顺序

    我正在解析两个大文件 GB 大小顺序 每个文件包含keys以及对应的values Some keys在两个文件之间共享 但对应的不同values 对于每个文件 我想写入一个新文件keys 以及对应的values with keys 代表 f
  • 无法访问视图内的 Blade 组件变量

    我在 Laravel 中遇到了这个非常奇怪的问题 我遇到一个问题 我的组件视图之一无法读取其类中定义的变量 这有点奇怪 因为我的项目中运行了几个组件 除了这个之外 它们都工作正常 所以我创建了一个新的 Laravel 项目来测试一些东西 想
  • 获取PDF文件中的超链接列表[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个 pdf 文件 我需要找到该文件中所有可用的超链接 然后对这些链接进行更改 我正在使用 C 我不想使用第三方工具 您可以使用i
  • 字符串替换数据框中的 ®、°F 等 UTF 特殊字符

    我想将数据帧所有列中的特殊字符 例如 和 F 替换为 html 代码 special char lt function df df gt mutate all funs str replace all x pattern replaceme
  • Rails 控制台在 Windows 中失败并显示“切换到检查模式”

    我创建了一个 Rails 项目rails new foo then cd foo 然后运行rails c 然后我收到这样的消息 DL is deprecated please use Fiddle Loading development e
  • 在单元测试中使用SpringRunner可以吗?

    我们正在与我的同事争论这种方法 他们说仅在集成或功能级别上使用 SpringRunner 问题是在下面的级别中使用它有什么优点和缺点 例如我有简单的豆 public class RewardDurationCalculator privat