我一直在网上看到很多关于这个问题的内容,但我找到的解决方案都没有为我工作。
我有一个测试类,以及我尝试测试的服务。
在测试课程中:
public class ElasticSearchSearchServiceImplTest{
@InjectMocks
private ElasticSearchSearchServiceImpl elasticSearchSearchService = new ElasticSearchSearchServiceImpl();
private SearchMyListCriteria searchMyListCriteria;
private SearchHitListCriteria searchHitListCriteria;
private SearchFieldLimitsCriteria searchFieldLimitsCriteria;
private SearchDetailCriteria searchDetailCriteria;
private SearchBrowseCriteria searchBrowseCriteria;
@Mock
private SearchRequestBuilder searchRequestBuilder;
@Mock
private SecurityService securityService;
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Client client;
@Mock
private ListenableActionFuture<SearchResponse> listenableActionFuture;
@BeforeMethod
public void setup() throws InterruptedException
{
MockitoAnnotations.initMocks(this);
SearchResponse sr = new SearchResponse();
Mockito.when(client.prepareSearch(Mockito.anyString())
.setQuery(Mockito.any(QueryBuilder.class))
.addFields(Mockito.anyObject())
.setFrom(Mockito.anyInt())
.setSize(Mockito.anyInt())
).thenReturn(searchRequestBuilder);
Mockito.when(securityService.isAccountabilityEnabled()).thenReturn(false);
Mockito.when(searchRequestBuilder.execute()).thenReturn(listenableActionFuture);
Mockito.when(listenableActionFuture.actionGet()).thenReturn(sr);
searchMyListCriteria = buildSearchCriteriaBase();
searchHitListCriteria = buildSearchHitListCriteria();
searchFieldLimitsCriteria = buildSearchFieldLimitsCriteria();
searchDetailCriteria = buildSearchDetailCriteria();
searchBrowseCriteria = buildSearchBrowseCriteria();
}
@Test
public void testDoMyListSearch()
{
SearchResponse searchResponse = new SearchResponse();
Boolean execOk = false;
try {
searchResponse = elasticSearchSearchService.doMyListSearch(searchMyListCriteria);
Assert.assertNotNull(searchResponse);
execOk = true;
}catch (Exception e){
e.printStackTrace();
}
Assert.assertTrue(execOk);
}
然后,在ElasticSearchSearchServiceImpl.java中,我有这个方法,我在测试中调用:
@Override
public SearchResponse doMyListSearch(SearchMyListCriteria criteria) throws Exception
{
SearchTimer t = new SearchTimer();
SearchResponse resp = null;
int size = criteria.getDocIds().size();
if(!criteria.getDocIds().isEmpty())
{
String indexName = getSearchAlias(criteria);
String[] ids = criteria.getDocIds().toArray(new String[criteria.getDocIds().size()]);
IdsQueryBuilder qb = QueryBuilders.idsQuery(getESTypes(criteria));
qb.addIds(ids);
SearchDataSourceAccountabilityEnum requiredAcc = securityService.isAccountabilityEnabled() && !criteria.getPermissions().isSuperUser()
? getAccountabilityForDataSources(criteria)
: SearchDataSourceAccountabilityEnum.NONE;
List<QueryBuilder> filters = new ArrayList<>();
addSecurityToFilter(filters, criteria, requiredAcc);
QueryBuilder filter = ElasticSearchUtils.and(filters);
QueryBuilder fqb = filter == null ? qb : QueryBuilders.boolQuery().must(qb).filter(filter);
SearchRequestBuilder req = client.prepareSearch(indexName)
.setQuery(fqb)
.addFields(determineMyListFieldsToReturn(criteria))
.setFrom(0)
.setSize(size);
resp = req.execute().actionGet();
}
long searchMillis = t.getElapsedMillis();
logPerform("Query Execution time for my list search " + criteria.toString() + COLON_SPACE + searchMillis + MILLISECONDS_MARKER);
return resp;
}
问题是,当它通过ElasticSearchSearchServiceImpl#doMyListSearch at line&#34; resp = req.execute()。actionGet();&#34;它抛出了以下异常:
java.lang.ClassCastException: org.mockito.internal.creation.cglib.ClassImposterizer$ClassWithSuperclassToWorkAroundCglibBug$$EnhancerByMockitoWithCGLIB$$db3b9e0a cannot be cast to org.elasticsearch.action.search.SearchResponse
at com.sirsidynix.bcss.search.biz.svc.impl.ElasticSearchSearchServiceImpl.doMyListSearch(ElasticSearchSearchServiceImpl.java:228)
at com.sirsidynix.bcss.search.biz.svc.impl.ElasticSearchSearchServiceImplTest.testDoMyListSearch(ElasticSearchSearchServiceImplTest.java:116)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:714)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:901)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1231)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at org.testng.TestRunner.privateRun(TestRunner.java:767)
at org.testng.TestRunner.run(TestRunner.java:617)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:334)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:329)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:291)
at org.testng.SuiteRunner.run(SuiteRunner.java:240)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1198)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1123)
at org.testng.TestNG.run(TestNG.java:1031)
at org.testng.remote.AbstractRemoteTestNG.run(AbstractRemoteTestNG.java:132)
at org.testng.remote.RemoteTestNG.initAndRun(RemoteTestNG.java:236)
at org.testng.remote.RemoteTestNG.main(RemoteTestNG.java:81)
我已尝试过网络上的大多数解决方案,似乎没有什么对我有用。如果您有任何建议我很感激。
问候!
答案 0 :(得分:1)
您是否尝试将测试减少到导致测试失败的最小代码?
您认为这是泛型问题。如果是这样,那么像下面那样简单的事情也会失败:
@Mock
private ListenableActionFuture<SearchResponse> listenableActionFuture;
@BeforeMethod
public void setup() throws InterruptedException {
MockitoAnnotations.initMocks(this);
SearchResponse sr = new SearchResponse();
Mockito.when(listenableActionFuture.actionGet()).thenReturn(sr);
}
@Test
public void testDoMyListSearch() {
SearchResponse sr = listenableActionFuture.actionGet();
}
是吗?我的猜测不是......我认为它更可能是由于深层存根以及深层存根返回与你在{{返回'的模拟相同类型的模拟这一事实。 1}}。我想知道是否使用thenReturn
甚至是必要的,或者如果深度存根只是让它工作并且#34;神奇地&#34;。
无论如何,我建议的是不断缩小空间以找出问题所在。此外,删除不必要的内容(例如thenReturn
)有助于人们了解代码并更快地帮助您。
(抱歉,我更愿意发表评论,但没有足够的声誉)。
答案 1 :(得分:0)
我认为客户端会为某些方法调用返回一个SearchRequestBuilder。所以你可能需要模拟一个SearchRequestBuilder。您是否可以在存根客户端之前尝试添加以下内容。
@BeforeMethod
public void setup() throws InterruptedException
{
MockitoAnnotations.initMocks(this);
SearchResponse sr = new SearchResponse();
SearchRequestBuilder requestBuilder = mock(SearchRequestBuilder.class, RETURNS_DEEP_STUBS);
when(client.prepareSearch(Matchers.any())).thenReturn(requestBuilder);
when(requestBuilder.setQuery(Matchers.any())).thenReturn(requestBuilder);
when(requestBuilder.addFields(Matchers.any())).thenReturn(requestBuilder);
when(requestBuilder.setFrom(Matchers.anyInt())).thenReturn(requestBuilder);
when(requestBuilder.setSize(Matchers.anyInt())).thenReturn(requestBuilder);
MockitoAnnotations.initMocks(this);
SearchResponse sr = new SearchResponse();
Mockito.when(client.prepareSearch(Mockito.anyString())
.setQuery(Mockito.any(QueryBuilder.class))
.addFields(Mockito.anyObject())
.setFrom(Mockito.anyInt())
.setSize(Mockito.anyInt())
).thenReturn(searchRequestBuilder);