[英]Mockito - Invalid use of Matchers Exception
當我使用以下語句時,我得到了 Invalid use of matchers 異常。 Mockito.when(CrossSellOffersRetrievalService.isHourInInterval(Mockito.anyString(), Mockito.anyString(), Z4D1142CA816EAC3E33B383BC0B537Z.anyString(), ()Z4D1142CA816EAC3E33B383BC0B537Z.
如何避免這種異常?
@Component
public class CrossSellOffersRetrievalService {
@Autowired
private CrossSellOffersRetrieval crossSellOffersRetrieval;
public List<CrossSellOffer> getApplicableOffers(String channelId, String customerId, String cinSuffix, String countryCode,
String interactionPoint, String sessionId, Integer numberOfOffers)throws CrossSellOffersException {
if (isOnLineServerTime()) {
if (numberOfOffers == null) {
numberOfOffers = 1;
}
List<CrossSellOffer> crossSellOffersList = crossSellOffersRetrieval.getApplicableOffers(channelId, customerId, cinSuffix,
countryCode, interactionPoint, sessionId,numberOfOffers);
return crossSellOffersList;
} else {
throw new CrossSellOffersException(Constants.ERROR_CODE, Constants.WRONG_SERVER_TIME);
}
}
public static boolean isHourInInterval(String target, String start, String end) {
return ((target.compareTo(start) >= 0) && (target.compareTo(end) <= 0));
}
public boolean isOnLineServerTime() {
String serverTime = DateTimeFormatter.ofPattern("HH.mm").format(LocalDateTime.now(ZoneId.of("Asia/Singapore")));
boolean value = isHourInInterval(serverTime,"08.00","23.15");
return value;
}
}
@RunWith(MockitoJUnitRunner.class)
public class CrossSellOffersRetrievalServiceTest {
@InjectMocks
private CrossSellOffersRetrievalService crossSellOffersRetrievalService;
@Mock
private CrossSellOffersRetrieval crossSellOffersRetrieval;
@Test
public void getApplicableOffersTest() throws CrossSellOffersException {
Mockito.when(CrossSellOffersRetrievalService.isHourInInterval(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(true);
Mockito.when(crossSellOffersRetrieval.getApplicableOffers(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), 1)).thenReturn(CrossSellOffersRetrievalHandlerTest.sampleCrossSellOffersList());
List<CrossSellOffer> crossSellOffersList = crossSellOffersRetrievalService.getApplicableOffers("MBSG", "S7754061Z", "00", "SG", "NEW_CC_ADDON", "IBOXS007", 1);
}
}
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at com.dbs.crossselloffers.offers_retrieval.CrossSellOffersRetrievalServiceTest.getApplicableOffersTest(CrossSellOffersRetrievalServiceTest.java:12)
-> at com.dbs.crossselloffers.offers_retrieval.CrossSellOffersRetrievalServiceTest.getApplicableOffersTest(CrossSellOffersRetrievalServiceTest.java:12)
-> at com.dbs.crossselloffers.offers_retrieval.CrossSellOffersRetrievalServiceTest.getApplicableOffersTest(CrossSellOffersRetrievalServiceTest.java:12)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
您不能在驗證或存根之外使用參數匹配器。
您的CrossSellOffersRetrievalService
沒有被嘲笑。 它是CrossSellOffersRetrievalService
的一個實際實例,用模擬實例化。 請參閱@InjectMocks
文檔。
因此,您正在嘗試存根不是模擬的東西。 如果您不想調用實際的isHourInInterval()
方法,請考慮 mocking 或部分 mocking 。 為此,您可能希望使該方法成為非靜態方法。 您可以模擬 static 方法,但這通常不是最好的做法。
附加說明:
由於您正在測試CrossSellOffersRetrievalService
,因此您可能不想模擬或部分模擬它 - 因為如果這樣做,您並沒有測試它的真正功能。 此外,您可能確實想檢查您的 output 是否符合您的預期,而不僅僅是您可以調用類的方法。
您可以spy
CrossSellOffersRetrievalService
的實際實例,但我建議編寫簡單的測試,例如方法:
when... thenReturn
來處理方法中的模擬調用。對每種方法的所有重要情況重復此操作,直到涵蓋每種方法。
如果此方法對您的 class 來說很困難,請考慮更改 class。 例如,如果mock
或構建輸入來滿足isHourInInterval
很痛苦,則將該方法封裝在一個單獨的 object 中,然后將其注入到您的CrossSellOffersRetrievalService
中。 您甚至可以將其設為 static 內部 class,如果它真的與其他任何東西無關。 然后,在測試時,注入一個總是返回 true 的模擬。
您正在嘗試存根 static 方法。 Mockito 不這樣做。
您在以下行中也遇到了錯誤,其中您將匹配器和非匹配器 arguments 混合到存根調用中(您需要將1
更改為eq(1)
)。
無論如何,看看您要測試的 class ,它看起來在一天中的不同時間表現不同。 因此,您可能需要對其在 8:00 到 23:15 之間的行為進行測試,並對其在這些時間之外的行為進行其他測試。
您將需要Clock
class 來設置這樣的測試。 在Unit testing a class with a Java 8 Clock中有一些關於如何做到這一點的信息
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.