java—如何使用mockito测试具有静态方法的给定类

a5g8bdjr  于 2021-07-14  发布在  Java
关注(0)|答案(2)|浏览(433)
import com.ssctech.eventmsg.app.model.EstimatedCash; 
import com.ssctech.eventmsg.app.properties.KongAPIProperties;
import lombok.extern.slf4j.Slf4j; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.beans.factory.annotation.Qualifier; 
import org.springframework.stereotype.Service; 
import org.springframework.web.reactive.function.client.WebClient; 

import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId;

public class KongAPIService {

    public static final String KONG_REGISTRATION_ID = "kong";

    @Autowired
    @Qualifier("kongApi")
    private WebClient webClient;

    @Autowired
    private KongAPIProperties kongAPIProperties;

    public EstimatedCash getEstimatedCash(String fundSponsorId, String positionId, String transId1, String transId2, String system) {

        try {
            return webClient.get()
                .uri(kongAPIProperties.getCashAvailabilityUri(), positionId, transId1, transId2)
                .attributes(clientRegistrationId(KONG_REGISTRATION_ID))
                .header("authorizationContext", "operator=" + kongAPIProperties.getAuthorizationContext())
                .header("fundSponsorId", fundSponsorId)
                .header("securityChannel", kongAPIProperties.getSecurityChannel())
                .header("system", system)
                .header("tenant", kongAPIProperties.getTenant())
                .retrieve()
                .bodyToMono(EstimatedCash.class)
                .block();
        } catch(Exception e) {
            log.error("Cannot get Cash Availability Info from API for " + "transId1 = " + transId1 + " / " + "transId2 = " + transId2, e);
            return new EstimatedCash();
        }
    }

}
``` `clientRegistrationId(KONG_REGISTRATION_ID)` 这是我写不出来的静态方法 `junit` 测试此方法如何在不使用 `PowerMock` 通过使用 `mockito` 只是。

package com.ssctech.eventmsg.app.service;

import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.when;
import static org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.web.reactive.function.client.WebClient;
import org.mockito.Matchers;

import com.ssctech.eventmsg.app.model.EstimatedCash;
import com.ssctech.eventmsg.app.properties.KongAPIProperties;

import reactor.core.publisher.Mono;

@RunWith(MockitoJUnitRunner.class)
public class KongAPIServiceTest {
@InjectMocks
KongAPIService KongApiService;
@Mock
WebClient webClient;
@Mock
WebClient.RequestBodyUriSpec requestBodyUriSpec;
@Mock
WebClient.RequestHeadersUriSpec requestHeadersUriSpec;
@Mock
WebClient.RequestHeadersSpec requestHeadersSpec;
@Mock
WebClient.RequestBodySpec requestBodySpec;
@Mock
WebClient.ResponseSpec responseSpec;
@Mock
EstimatedCash estimate;
@Mock
Mono mono;
@Mock
Consumer<Map<String, Object>> consumer;
private KongAPIProperties kongAPIProperties=new KongAPIProperties();
Map<String, Object> mp = new HashMap<>();

@Before
public void setup() {
    KongApiService = new KongAPIService();
    MockitoAnnotations.initMocks(this);
}

@Test
public void postTest() throws Exception {
    when(webClient.get()).thenReturn(requestHeadersUriSpec);
    kongAPIProperties.setCashAvailabilityUri("available");
    when(requestHeadersUriSpec.uri(Matchers.any(String.class), Matchers.any(String.class), Matchers.any(String.class),
            Matchers.any(String.class))).thenReturn(requestHeadersUriSpec);

// when(requestHeadersSpec.attributes(consumer)).thenReturn(requestBodySpec);
// when(requestHeadersSpec.header(Matchers.any(String.class), Matchers.any(String.class)))
// .thenReturn(requestHeadersSpec);
// when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
// when(responseSpec.bodyToMono(Matchers.any(Class.class))).thenReturn(mono);
// when(mono.block()).thenReturn(new String());
assertNotNull(KongApiService.getEstimatedCash("001", "1", "id1", "id2", "mfa"));
}

}

kiayqfof

kiayqfof1#

不可能使用 mockito 只是。

3htmauhk

3htmauhk2#

嘲笑整个世界没有什么价值 WebClient 交互,因为你最终模仿一切,并字面上与你的实现副本。这很脆弱,在重构代码时也没有帮助。
在测试与http客户机交互的类时,我建议生成本地http服务器并模拟http响应。mockwebserver非常适合这个用例或wiremock/mockserver。
大多数本地模拟服务器允许在之后检索请求,以便您可以检查是否存在所有头。
对于静态方法访问,可以使用mockito来模拟方法(如果需要):

try (MockedStatic<ServerOAuth2AuthorizedClientExchangeFilterFunction> mockedStatic = Mockito.mockStatic(ServerOAuth2AuthorizedClientExchangeFilterFunction.class)) {

  mockedStatic
    .when(() -> ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(eq("KONG_REGISTRATION_ID")))
    .thenReturn("YOUR_ID");

  // ...
}

如果您仍计划编写测试并模拟所有内容,请考虑使用深存根,以避免在测试中使用大量样板代码。

相关问题