对存储库进行单元测试时出现类转换异常

问题描述

我正在将应用程序从 Java8 迁移到 Java11 并使用以下依赖项
Java 11
春天:5.1.0
powermock-module-junit4:2.0.2
powermock-api-mockito2:2.0.2
模拟核心:2.27.0
JUnit:4.12

我有存储库,我不得不测试它的功能。在我的单元测试案例中,我使用 powermock 来模拟对象。假设我在 SomeRepoImpl.java

中测试了这个方法
public Page<Locale> someMethod(List<String> queryFields,Map<String,Object> filters,Pageable p) {
    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Locale> criteria = builder.createquery(Locale.class);
    Root<Locale> root = criteria.from(Locale.class);
    Selection<?>[] s = new Selection<?>[queryFields.size()];
    int i = 0;
    for (String field : queryFields) {
        s[i++] = CriteriaUtils.getField(root,field);
    }
    criteria.select(builder.construct(Locale.class,s));

    Sort sort = p.getSort();
    if (null != sort) {
        List<Order> list = new ArrayList<Order>(3);
        Iterator<Sort.Order> item = sort.iterator();
        Sort.Order o = null;
        while (item.hasNext()) {
            o = item.next();
            if (o.isAscending()) {
                list.add(builder.asc(root.get(o.getproperty())));
            } else {
                list.add(builder.desc(root.get(o.getproperty())));
            }
        }
        criteria.orderBy(list);
    }

    Predicate[] predicates = null;
    if (null != filters && filters.size() > 0) {
        predicates = new Predicate[filters.size()];
        i = 0;
        for (Map.Entry<String,Object> entry : filters.entrySet()) {
            String key = entry.getKey();
            Object val = entry.getValue();
            predicates[i++] = builder.equal(CriteriaUtils.getField(root,key),val);
        }
        if (null != predicates) {
            criteria.where(predicates);
        }
    }
    System.err.println("The value of P: "+p);
    List<Locale> content = em.createquery(criteria).setFirstResult(p.getoffset()).setMaxResults(p.getPageSize())
            .getResultList();
    Long count = (Long)getCountQuery(predicates).getSingleResult();
    return new PageImpl<Locale>(content,p,count);
}

对于上述存储库功能,我编写了以下测试代码(如果我错了,请纠正我),我是新手。

@RunWith(powermockrunner.class)
@powermockrunnerDelegate(SpringJUnit4ClassRunner.class)
@PowerMockIgnore({ "javax.management.*","sun.*","javax.net.ssl.*" })
@ContextConfiguration(locations = { "classpath*:/spring/test-context.xml" })
public class SomeRepositoryTest {

@Mock
EntityManager em;
@Mock
Query query;
@Mock
CriteriaQuery<Locale> criteriaQuery;
@Mock
CriteriaBuilder criteriaBuilder;
@Mock
Root<Locale> root;
@Mock
Predicate predicate;
@Mock
Selection<Locale> selection;
@Mock
Path<Object> path;
@Mock
CompoundSelection<Locale> compondSelection;
@Mock
TypedQuery<Locale> typedQuery;
@Mock
CriteriaQuery<Long> criteriaQueryLong;
@Mock
TypedQuery<Long> typedQueryLong;
@Mock
Root<Locale> policyRootLong;
@InjectMocks
SomeRepoImpl someRepoImpl;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
    
    List<Locale> listofLocale = new ArrayList<>();
    Locale locale = new Locale("testCode");
    listofLocale.add(locale);
    
    Selection<?>[] s = new Selection<?>[1];
    powermockito.when(em.getCriteriaBuilder()).thenReturn(criteriaBuilder);
    powermockito.when(criteriaBuilder.createquery(Locale.class)).thenReturn(criteriaQuery);
    powermockito.when(criteriaQuery.from(Locale.class)).thenReturn(root);
    powermockito.when(criteriaQuery.select(root)).thenReturn(criteriaQuery);
    powermockito.when(root.get("langCode")).thenReturn(path);
    s[0] = path;
    powermockito.when(criteriaBuilder.construct(Locale.class,s)).thenReturn(compondSelection);
    powermockito.when(criteriaQuery.select(compondSelection)).thenReturn(criteriaQuery);
    powermockito.when(em.createquery(criteriaQuery)).thenReturn(typedQuery);
    powermockito.when(typedQuery.setFirstResult(0)).thenReturn(typedQuery);
    powermockito.when(typedQuery.setMaxResults(4)).thenReturn(typedQuery);
    powermockito.when(typedQuery.getResultList()).thenReturn(listofLocale);
    
    //For Long
    powermockito.when(criteriaBuilder.createquery(Long.class)).thenReturn(criteriaQueryLong);
    powermockito.when(criteriaQueryLong.from(Locale.class)).thenReturn(policyRootLong);
    powermockito.when(criteriaQueryLong.select(criteriaBuilder.count(policyRootLong))).thenReturn(criteriaQueryLong);
    powermockito.when(em.createquery(criteriaQueryLong)).thenReturn(typedQueryLong);
    powermockito.when(typedQueryLong.getSingleResult()).thenReturn(2L);
    
}

@Test
public void performtest() {
    List<String> queryFields = new ArrayList<String>();
    queryFields.add("one");
    queryFields.add("two");
    queryFields.add("three");
    queryFields.add("four");
    
    Map<String,Object> filters = null;
    Pageable page = new PageRequest(0,4);
    
    powermockito.when(localerepo.loadLocaleListByCondition(queryFields,filters,page)).thenReturn(new PageImpl<Locale>(new ArrayList<Locale>() {{
        add(new Locale("testCode"));
    }},page,2));
    
    Page<Locale> result = someRepoImpl.loadLocaleListByCondition(queryFields,page);
    Assert.assertNotNull(result);
    Assert.assertTrue(result.getContent() != null);
    Assert.assertTrue(result.getTotalElements() > 0);
}

}

我收到以下异常

java.lang.classCastException: class org.springframework.data.domain.PageImpl cannot be cast to class java.lang.Long (org.springframework.data.domain.PageImpl is in unnamed module of loader org.powermock.core.classloader.javassist.JavassistMockClassLoader @6483f5ae; java.lang.Long is in module java.base of loader 'bootstrap')
at com.somepackage.someRepoImpl.someMethod(SomeRepoImpl.java:90)
at com.somepackage.someRepositoryTest.performTest(SomeRepositoryTest.java:140)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)

我一直试图理解这一点,但无法理解。任何帮助都会非常有用。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)