![](/img/trans.png)
[英]How to deal with test class who is having dependency on abstract method using junit mockito in java
[英]how to test given class having static method using mockito
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)
這是 static 方法我無法編寫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"));
}
}
僅使用mockito
來模擬 static 方法是不可能的。
mocking 整個WebClient
交互幾乎沒有什么價值,因為您最終得到 mocking 一切,並且實際上是您的實現的副本。 這很脆弱,在重構代碼時無濟於事。
在測試與 HTTP 客戶端交互的 class 時,我建議生成本地 HTTP 服務器並模擬 Z293C9EA246FF989A6 響應。 MockWebServer非常適合此用例或WireMock / MockServer 。
這些本地模擬服務器中的大多數都允許在之后檢索請求,以便您可以檢查是否存在所有標頭。
對於 static 方法訪問,可以使用 Mockito 模擬該方法(如果需要):
try (MockedStatic<ServerOAuth2AuthorizedClientExchangeFilterFunction> mockedStatic = Mockito.mockStatic(ServerOAuth2AuthorizedClientExchangeFilterFunction.class)) {
mockedStatic
.when(() -> ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(eq("KONG_REGISTRATION_ID")))
.thenReturn("YOUR_ID");
// ...
}
如果您仍打算編寫測試並模擬所有內容,請考慮使用深度存根以避免測試中出現大量樣板代碼。
我有同樣的問題。 我找到了解決辦法。 像這樣使用Mockito.notNull()
:
when(requestBodyMock.attributes(notNull())).thenReturn(requestBodyMock);
我無法對此使用深度存根,這是行不通的。 希望這對其他人有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.