测试(junit)switch 语句中的默认情况?

问题描述 投票:0回答:4

我需要知道如何使用 junit 测试 switch 语句中的默认情况。我无法更改代码本身,并且我正在尝试 100% 的覆盖率,但我不知道如何测试我的默认值。有帮助吗?

public Hello helloSwitch() {
        Hello hi = Hello.A;
        switch (this) {
        case A:
            hi = Hello.B;
            break;
        case B:
            hi = Hello.C;
            break;
        case C:
            hi = Hello.A;
            break;
        default:
            hi = Hello.A;
            break;
        }

我不得不对代码进行一些修改,很抱歉它看起来很愚蠢。我只需要知道如何编写 junit 来测试默认值,我已经测试了其他所有内容。

我无法更改此代码。

编辑:已更改

编辑:这段代码并不重要,我只需要知道如何编写默认的单元测试

编辑:我无法更改代码本身,我只是编写测试。不过我需要 100% 的覆盖率。

java testing junit switch-statement default
4个回答
1
投票

让我假设“hallo”是在给定方法之外的某个位置设置的变量。让我进一步假设 Enum 类型当前仅允许 switch 语句中存在值。 在这种情况下,您可以使用“null”来触发默认情况。在这种情况下,默认语句是无法访问的,根本不应该存在。虽然可能仍然有方法可以“测试”这一点 - 意思是执行运行测试的代码 - 但这不会增加任何好处。 如果您有更多可用的枚举常量,请选择默认情况下涵盖的任何常量。

正如一些人已经提到的:

  • 死代码不能也不应该被测试而应该被删除。
  • 100% 的测试覆盖率听起来不错,但通常不是一个现实或明智的目标
  • 在我看来,测试甚至不应该了解方法中的代码,而应该将方法作为黑盒进行测试。

0
投票

如果您正在使用 JaCoCo,那么也许可以投票支持此改进,以忽略无法覆盖的默认情况:https://github.com/jacoco/jacoco/issues/1211


0
投票

如果需要测试使用枚举的 switch 语句中的默认情况,可以通过使用 Mockito 创建枚举的模拟来实现。该模拟可以模拟实际枚举中不存在的枚举值,从而强制开关达到默认情况。

这是分步指南:

逐步解决方案:

  1. 为不支持的枚举值创建模拟

使用 Mockito 创建枚举的模拟。该模拟将表示不支持的值,该值不属于实际枚举。

  1. 模拟values()方法:

使用Mockito中的MockedStatic来模拟枚举的values()方法。这允许您将模拟枚举值包含在 value() 返回的数组中,从而模拟意外枚举值的存在。

  1. 调用被测方法

如果您正在测试的方法是私有的或受保护的,请使用反射来调用它。这样,您可以直接将模拟枚举值传递给方法并强制 switch 语句命中默认情况。

  1. 断言预期异常:

使用assertThrows确保方法在遇到不支持的枚举值时抛出预期的异常。

示例代码

enum ExampleEnum {
    A, B, C, D
}

测试方法:

    @Test
    void testMethodWithUnsupportedEnum() throws NoSuchMethodException {
        try (MockedStatic<ExampleEnum> mockedStatic = Mockito.mockStatic(ExampleEnum.class)) {
            // Create a mock for the unsupported enum value
            ExampleEnum UNSUPPORTED = Mockito.mock(ExampleEnum.class);
            Mockito.when(UNSUPPORTED.ordinal()).thenReturn(99);  // Set a high ordinal value
            Mockito.when(UNSUPPORTED.name()).thenReturn("UNSUPPORTED");
            Mockito.when(UNSUPPORTED.toString()).thenReturn("UNSUPPORTED");

            // Mock the values() method to include the unsupported enum value
            mockedStatic.when(ExampleEnum::values)
                    .thenReturn(new ExampleEnum[]{
                            ExampleEnum.A,
                            ExampleEnum.B,
                            ExampleEnum.C,
                            ExampleEnum.D,
                            UNSUPPORTED
                    });

         // the params in getDeclaredMethod (): method name, and passe the param type in your method for exemple here our method have two params (String a, ExampleEnum exp)
          //use reflection to access the method if it's not public
              Method method = ExampleClass.class.getDeclaredMethod("methodUnderTest", String.class, ExampleEnum.class);
            method.setAccessible(true);

            // Assert that the default case throws the expected exception
            assertThrows(InvocationTargetException.class, () -> {
                method.invoke(null, "testValue", UNSUPPORTED);
            });
        }
    }

-3
投票

访问此链接可以帮助您: [JUnit 是用于测试 Java 单元(即 Java 类)的标准化框架。 JUnit 可以自动化,以减少测试中的部分工作。

假设您创建了一个具有三个值的枚举类型:GREEN、YELLOW 和 RED。清单 1 包含代码: http://www.dummies.com/programming/java/using-junit]1

© www.soinside.com 2019 - 2024. All rights reserved.