【问题标题】:How to Mock a Static function with WebMvcTest in Springboot如何在 Springboot 中使用 WebMvcTest 模拟静态函数
【发布时间】:2022-07-09 08:51:00
【问题描述】:

@WebMvcTest 注解中是否有任何功能可用于测试类的静态函数?

【问题讨论】:

  • @Kai-ShengYang 您的回复没有帮助,因为问题是:MockedStatic 是线程本地的。这意味着,通常已经预先加载了一个类,并且根据提问者的需要,这可能是不可能的Mockito#mockStatic。我目前面临与NetworkInterface 相同的问题。我可以在那里模拟静态方法,但是@ContextConfiguration 已经运行了。

标签: mockito spring-boot-test mockmvc


【解决方案1】:

因为我相信我发现了它(并且在链接的 baeldung-tutorial 中缺少它),所以这里有一个示例(我目前不使用 @WebMvcTest,我正在测试一个配置对象):

(请参阅下面的解释)

(imports omitted in favor of brevity)

@Slf4j
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = ServerObjectConfiguration.class)
class ServerObjectConfigurationTest {

    // 192.168.178.82
    private static final byte[] EXAMPLE_IP_V4 = {-64, -88, -78, 82};
    // 2001:0db8:85a3:0000:0000:8a2e:0370:7334
    private static final byte[] EXAMPLE_IP_V6 = {32, 1, 13, -72, -123, -93, 0, 0, 0, 0, -118, 46, 3, 112, 115, 52};
    private static final byte[] EXAMPLE_MAC_ADDRESS = {-68, -48, 116, 9, -47, 11};
    private static final MockedStatic<NetworkInterface> mockedNetworkInterface = Mockito.mockStatic(NetworkInterface.class);
    private static final MockedStatic<InetAddress> mockedInetAddress = Mockito.mockStatic(InetAddress.class);

    @Autowired
    private ServerObjectConfiguration serverObjectConfiguration;

    @Autowired
    private Server server;

    @SneakyThrows
    @BeforeAll
    static void setUp() {
        // This is SPARTAAA... or rather: crazy, because everything java.net seems to smell of bad design decisions
        InetAddress ipV4InetAddress = mock(InetAddress.class);
        when(ipV4InetAddress.getAddress())
                .thenReturn(EXAMPLE_IP_V4);
        when(ipV4InetAddress.isSiteLocalAddress())
                .thenReturn(true);

        InetAddress ipV6InetAddress = mock(InetAddress.class);
        when(ipV6InetAddress.getAddress())
                .thenReturn(EXAMPLE_IP_V6);
        when(ipV6InetAddress.isSiteLocalAddress())
                .thenReturn(true);

        InterfaceAddress ipV4InterfaceAddress = mock(InterfaceAddress.class);
        when(ipV4InterfaceAddress.getAddress())
                .thenReturn(ipV4InetAddress);

        InterfaceAddress ipV6InterfaceAddress = mock(InterfaceAddress.class);
        when(ipV6InterfaceAddress.getAddress())
                .thenReturn(ipV6InetAddress);

        NetworkInterface networkInterface = mock(NetworkInterface.class);
        when(networkInterface.getInterfaceAddresses())
                .thenReturn(List.of(ipV4InterfaceAddress, ipV6InterfaceAddress));
        when(networkInterface.getHardwareAddress())
                .thenReturn(EXAMPLE_MAC_ADDRESS);

        mockedInetAddress.when(() -> InetAddress.getByAddress(EXAMPLE_IP_V4))
                .thenReturn(ipV4InetAddress);
        mockedInetAddress.when(() -> InetAddress.getByAddress(EXAMPLE_IP_V6))
                .thenReturn(ipV6InetAddress);

        mockedNetworkInterface.when(() -> NetworkInterface.getByInetAddress(ipV4InetAddress))
                .thenReturn(networkInterface);
        mockedNetworkInterface.when(() -> NetworkInterface.getByInetAddress(ipV6InetAddress))
                .thenReturn(networkInterface);
        mockedNetworkInterface.when(NetworkInterface::networkInterfaces)
                .thenReturn(Stream.of(networkInterface));
    }

    @AfterAll
    static void tearDown() {
        mockedInetAddress.close();
        mockedNetworkInterface.close();
    }

    @SneakyThrows
    @Test
    void test_serverObjectIsConfiguredAsExpected() {
        // the bean uses NetworkInterface to get the IP-addresses and MAC-address assertThat(server.getMacAddresses()).containsOnly(EXAMPLE_MAC_ADDRESS);
        assertThat(server.getIpAddresses()).containsExactlyInAnyOrder(EXAMPLE_IP_V4, EXAMPLE_IP_V6);
    }
}

要模拟静态方法,您必须@BeforeAll (JUnit5) 注释方法中进行,该方法是静态的。原因是,您希望尽可能早地在测试中模拟静态方法。

我尝试使用线程本地 Mockito#mockStatic 调用,但由于我的 bean 在测试开始之前就已经初始化,所以我尝试模拟相关的静态方法为时已晚。

这种方法确实有效,包含 IP 地址和 MAC 地址的 Server-bean 接收到我期望的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多