【问题标题】:JMockit: IntelliJ vs mvn test command line with surefire - Different behaviorsJMockit:IntelliJ vs mvn test 命令行 with surefire - 不同的行为
【发布时间】:2018-08-26 10:54:39
【问题描述】:

在使用带有 @Capturing 注释的 JMockit 实现单元测试时 和“捕获”变量的验证块我有 2 个结果:

  1. IntelliJ:我可以成功运行和调试,验证验证是否正确。

  2. 使用mvn test 使用命令行 (cmd) 执行相同的测试代码会引发“缺少调用”。

如果使用 cmd,@Capturing 的行为似乎类似于 @Mocked。因为如果我将@Capturing 更改为@Mocked,这是确切的行为。

这是什么原因?

设置:
IntelliJ:2017.3.4
Java 8
JMockit 1.35

【问题讨论】:

  • 您能否展示一个示例测试,它在 Maven 中失败但在 IntelliJ 中失败?您使用的是什么版本的 Maven 和 Surefire 插件?
  • 您好 Rogério,sn-p 如下所示:
  • 嗨 Rogerio,由于内部政策,我只能分享有关 cmd 行中提供的错误的最小部分:缺少 1 次调用:manager#execute(任何字符串,任何字符串,任何计算配置,任何 java .util.Map)
  • maven 版本:3.5.2;surefire:2.20.1
  • 我需要的是一个重现问题的完整示例测试;不需要是您的真实代码。您提供的代码有很多不必要的细节,并且没有显示任何正在测试的代码。此外,它应该添加到问题中,而不是答案中。

标签: java intellij-idea jmockit maven-surefire-plugin


【解决方案1】:

参考:

@Test
public void test(final @Mocked ProfileMgr profileMgr,
                                             final @Capturing Manager manager) throws Exception {


    final String id = “1234”;
    Final String modelId = “567”;
    final Map<String, String> effectiveProps = ImmutableMap.of("test.key", "test.value",
                                                               "ppp.key", "ppp.value"
    );

    final Optional<String> option = Optional.of("123");
    new Expectations() {{
        profileMgr.mergedProperties(
                id,IMPL_1,
                (Map<String, String>) any,
                option
        );
        result = effectiveProps;
    }};

    this.mainManager
            .run(
                    id,
                    modelId,
                    new JobRequestWrapper<>(config, IMPL_1, option);
            );

    new Verifications() {{
        final Map<String, String> params;
        manager.execute(
                anyString,
                anyString,
                (CalculationConfig) any,
                params = withCapture()
        );
        times = 1;
        assertThat(params)
                .withFailMessage("params must have content.")
                .isNotNull()
                .isNotEmpty();
        assertThat(params)
                .withFailMessage("params must have same injected entry.")
                .isEqualTo(effectiveProps);
    }};
}

【讨论】:

    【解决方案2】:

    一般来说,这类问题通常是由于 maven 在 jvm 的一次执行中运行了多个测试。当您在 IntelliJ 中运行单个单元测试时,该测试被很好地隔离,但是当使用 maven 运行时,一个测试中全局变量的任何更改都可能对其他测试的执行产生意想不到的影响。

    这就是为什么人们应该避免在单元测试中改变(甚至使用)静态变量,如果你有启用弹簧的测试会改变你的上下文等,请使用@DirtiesContext

    我没有足够的具体信息来查明您案例中的确切问题,但我建议您开始寻找可能会改变其他测试行为的东西。也可以使用 IntelliJ 一次运行多个测试类,这样做可能更接近于 maven 运行测试的方式。

    【讨论】:

    • 这是不正确的。 Maven Surefire 和 IntelliJ 都为测试运行启动一个新的 JVM 实例,默认执行该实例中的所有测试。
    • 您好托布,感谢您的评论。那是我的第一个客人,一些变异状态,但我认为多次运行该类时会出现这种症状,而不仅仅是方法。但这发生在第一次运行。
    • @Rogério maven 执行中的测试共享同一个 jvm,因此任何静态变量在测试类和方法之间共享。我看不出您的评论与我的回答有任何矛盾。
    • 从任何 Java IDE(包括 IntelliJ)执行测试也是如此。此外,这与问题中描述的问题无关,发生在单个测试中。
    • 是的,但通常在 IntelliJ 中,一次会运行一个测试类。这也是为什么我建议尝试在 IntelliJ 中运行多个测试类,以查看它的行为是否更接近 maven 的做法。据我所知,OP 没有明确说明他的项目中的测试数量,所以如果你不是某种通灵者,你不能排除在 maven 构建中还有其他测试会影响有问题的测试(其中如前所述,当测试在 IntelliJ 中运行良好但在 maven 中运行良好时,通常会出现问题。)
    猜你喜欢
    • 2013-06-11
    • 2018-09-26
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多