我正在尝试为查询 dsl 编写测试用例,运行测试用例时出现空指针异常
DSL 类
QMyClass myClass= QMyClass.myClass;
queryFactory = new JPAQueryFactory(em);
JPAQuery<?> from = queryFactory.from(myClass);
JPAQuery<?> where = from
.where(prepdicates);
orderBy(orderSpecifier).offset(sortOrder.getOffset())
.limit(sortOrder.getPageSize());
**Junit test case:**
import javax.inject.Provider;
import javax.persistence.EntityManager;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.data.jpa.repository.support.QueryDslRepositorySupport;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.JPQLTemplates;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
@RunWith(PowerMockRunner.class)
public class MyClass{
@Mock
QueryDslRepositorySupport queryDslRepositorySupport;
@Mock
EntityManager entityManager;
@Mock
JPAQueryFactory queryFactory;
@Mock
JPAQuery step1;
@InjectMocks
MyClass myClass;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Provider<EntityManager> provider = new Provider<EntityManager>() {
@Override
public EntityManager get() {
return entityManager;
}
};
queryFactory = new JPAQueryFactory(JPQLTemplates.DEFAULT, provider);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void sampleTest() throws Exception {
QMyClass class= Mockito.mock(QMyClass.class);
Mockito.when(queryFactory.from(class)).thenReturn(step1);
Predicate step2 = Mockito.mock(Predicate.class);
Mockito.when(step1.where(step2)).thenReturn(step1);
OrderSpecifier step3 = Mockito.mock(OrderSpecifier.class);
Mockito.when(step1.orderBy(step3)).thenReturn(step1);
Mockito.when(step1.offset(Mockito.anyLong())).thenReturn(step1);
Mockito.when(step1.limit(Mockito.anyLong())).thenReturn(step1);
myClass.method("");
}
}
当我运行这个测试用例时,我在 sampleTest() 方法中的第 2 行出现空指针异常。我用谷歌搜索但没有找到任何关于这个的文章,不知道为什么这个 NE,即使在嘲笑查询之后
这是跟踪:
java.lang.NullPointerException
at com.querydsl.core.DefaultQueryMetadata.addJoin(DefaultQueryMetadata.java:154)
at com.querydsl.core.support.QueryMixin.from(QueryMixin.java:163)
at com.querydsl.jpa.JPAQueryBase.from(JPAQueryBase.java:77)
at com.querydsl.jpa.impl.JPAQueryFactory.from(JPAQueryFactory.java:116)
at
正如我在评论中提到的,你的问题是你没有使用模拟,而是使用真实的对象。
从设置方法中删除查询工厂初始化。
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
Provider<EntityManager> provider = new Provider<EntityManager>() {
@Override
public EntityManager get() {
return entityManager;
}
};
// remove this line
// queryFactory = new JPAQueryFactory(JPQLTemplates.DEFAULT, provider);
}
此外,您还需要更改您的实现,您不能在代码中使用queryFactory = new JPAQueryFactory(em);
,因为它不能被模拟。
相反,你可以做的是有一个返回JPAQueryFactory的方法,无论是从另一个类 - 你可以模拟 -
还是在同一方法中,
然后你需要监视你的类。
由于您没有为要测试的类添加代码(MyClass - 希望与同名的 UnitTest 不同?),另一种可能性是您尝试使用字段或构造函数注入(如使用注释所示),但代码中根本不应该为 JPAQueryFactory 创建对象。
这似乎也是错误的: 您应该将模拟注入到被测试的类中,而不是在单元测试类中。
@RunWith(PowerMockRunner.class)
public class MyClass{
...
@InjectMocks
MyClass myClass;