[英]Mockito - Invalid use of Matchers Exception
I am getting Invalid use of matchers Exception when i use the below statement.当我使用以下语句时,我得到了 Invalid use of matchers 异常。 Mockito.when(CrossSellOffersRetrievalService.isHourInInterval(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(true); Mockito.when(CrossSellOffersRetrievalService.isHourInInterval(Mockito.anyString(), Mockito.anyString(), Z4D1142CA816EAC3E33B383BC0B537Z.anyString(), ()Z4D1142CA816EAC3E33B383BC0B537Z.
How to avoid this exception?如何避免这种异常?
@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"))
You cannot use argument matchers outside of verification or stubbing.您不能在验证或存根之外使用参数匹配器。
Your CrossSellOffersRetrievalService
is not mocked.您的CrossSellOffersRetrievalService
没有被嘲笑。 It is an actual instance of CrossSellOffersRetrievalService
, instantiated with mocks.它是CrossSellOffersRetrievalService
的一个实际实例,用模拟实例化。 See the @InjectMocks
documentation .请参阅@InjectMocks
文档。
Therefore, you're trying to stub something which is not a mock.因此,您正在尝试存根不是模拟的东西。 Consider mocking or partially mocking it, if you don't want to call the actual isHourInInterval()
method.如果您不想调用实际的isHourInInterval()
方法,请考虑 mocking 或部分 mocking 。 To do this, you'd probably want to make the method non-static.为此,您可能希望使该方法成为非静态方法。 You can mock a static method but it's often not the best thing to do. 您可以模拟 static 方法,但这通常不是最好的做法。
An additional note:附加说明:
Since CrossSellOffersRetrievalService
is what you're testing , you probably don't want to mock or partial mock it - since if you do, you're not testing its real functionality.由于您正在测试CrossSellOffersRetrievalService
,因此您可能不想模拟或部分模拟它 - 因为如果这样做,您并没有测试它的真正功能。 In addition, you probably do want to check that your output is what you expect it to be, not just that you can call the class' methods.此外,您可能确实想检查您的 output 是否符合您的预期,而不仅仅是您可以调用类的方法。
You could spy
on an actual instance of CrossSellOffersRetrievalService
, but I'd suggest writing simple tests, eg for a method:您可以spy
CrossSellOffersRetrievalService
的实际实例,但我建议编写简单的测试,例如方法:
when... thenReturn
to handle mock calls in the method.使用您注入的模拟和when... thenReturn
来处理方法中的模拟调用。Repeat for all important cases for each method, until each method is covered.对每种方法的所有重要情况重复此操作,直到涵盖每种方法。
If this method is difficult for your class, consider changing the class.如果此方法对您的 class 来说很困难,请考虑更改 class。 For example, if it's a pain to mock
or build input to satisfy isHourInInterval
, encapsulate that method inside a separate object, which you inject into your CrossSellOffersRetrievalService
.例如,如果mock
或构建输入来满足isHourInInterval
很痛苦,则将该方法封装在一个单独的 object 中,然后将其注入到您的CrossSellOffersRetrievalService
中。 You can even make it a static inner class, if it's really not relevant to anything else.您甚至可以将其设为 static 内部 class,如果它真的与其他任何东西无关。 Then, when testing, inject a mock that always returns true.然后,在测试时,注入一个总是返回 true 的模拟。
You're trying to stub a static method.您正在尝试存根 static 方法。 Mockito doesn't do that. Mockito 不这样做。
You've also got an error on the following line, where you've got a mixture of matcher and non-matcher arguments to a stubbing call (you'll need to change 1
to eq(1)
).您在以下行中也遇到了错误,其中您将匹配器和非匹配器 arguments 混合到存根调用中(您需要将1
更改为eq(1)
)。
Anyway, looking at the class you're trying to test, it looks like it behaves differently at different times of the day.无论如何,看看您要测试的 class ,它看起来在一天中的不同时间表现不同。 So you're probably going to want tests for its behaviour between 8:00 and 23:15, and other tests for how it behaves outside those hours.因此,您可能需要对其在 8:00 到 23:15 之间的行为进行测试,并对其在这些时间之外的行为进行其他测试。
You're going to need the Clock
class to set up tests like that.您将需要Clock
class 来设置这样的测试。 There's some information about how to do that at Unit testing a class with a Java 8 Clock在Unit testing a class with a Java 8 Clock中有一些关于如何做到这一点的信息
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.