Java 使用querydsl模拟数据库查询-使用可选

Java 使用querydsl模拟数据库查询-使用可选,java,junit,mocking,guava,querydsl,Java,Junit,Mocking,Guava,Querydsl,我的应用程序在DB查询上编写测试有一些困难,它在mongo上使用querydsl。我发现了几个只对查询对象本身进行单元测试的人的例子,但我想更进一步,测试查询如何执行(如集成测试),而不必启动整个数据库过程。也就是说,只使用java工具模拟DB 我找不到任何相关的工具,例如DBUnit或DbSetup需要实际连接到DB。所以我开始编写自己的类,它几乎可以工作。其思想是使用com.mysema.query.collections.CollQuery和mockito模拟一个数据库,该数据库将接收我的

我的应用程序在DB查询上编写测试有一些困难,它在mongo上使用querydsl。我发现了几个只对查询对象本身进行单元测试的人的例子,但我想更进一步,测试查询如何执行(如集成测试),而不必启动整个数据库过程。也就是说,只使用java工具模拟DB

我找不到任何相关的工具,例如DBUnit或DbSetup需要实际连接到DB。所以我开始编写自己的类,它几乎可以工作。其思想是使用com.mysema.query.collections.CollQuery和mockito模拟一个数据库,该数据库将接收我的应用程序的查询,并带有一个包装器“CollQuery to query”。基本上,它是这样工作的:

public class MyServiceTest {

    private MyService service;
    private final Collection<MyObject> fakeTable = new ArrayList<>();

    @Before
    public void setup() {

        final Persister persister = mock(Persister.class);
        when(persister.query(any(Class.class)))
                // MockedQuery is the wrapper I wrote
                .thenReturn(new MockedQuery<>(QMyObject.myObject, fakeTable));

        service = new MyService(persister);
    }

    @Test
    public void shouldWork() {
        fakeTable.add(new MyObject("one"));
        fakeTable.add(new MyObject("two"));
        fakeTable.add(new MyObject("three"));

        final List<MyObject> result = service.getOne();
        // service.getOne would do something like:
        //  persister.query(QMyObject.myObject).where(QMyObject.myObject.name.eq("one")).list()

        assertThat(result).hasSize(1);
    }
}
公共类MyServiceTest{
私人MyService服务;
私有最终集合fakeTable=new ArrayList();
@以前
公共作废设置(){
final Persister Persister=mock(Persister.class);
当(persister.query(any(Class.Class)))
//MockedQuery是我编写的包装器
.thenReturn(新的MockedQuery(QMyObject.myObject,fakeTable));
服务=新的MyService(persister);
}
@试验
公共空间应该工作{
添加(新的MyObject(“一”));
添加(新的MyObject(“两”));
添加(新的MyObject(“三”));
最终列表结果=service.getOne();
//service.getOne将执行以下操作:
//persister.query(QMyObject.myObject).where(QMyObject.myObject.name.eq(“一”).list()
资产(结果).hasSize(1);
}
}
。。。基本上,它似乎是有效的!除了我的代码大量使用guava的可选代码外,这似乎是querydsl的一个问题。如果MyObject采用可选的,而不是字符串,则我会得到错误:

com.mysema.codegen.CodegenException: Compilation of public class     Q_01363784216_1275614662_1275614662_1573163836_01698119955_566403833 {

    public static Iterable<xxx.OpenedInterruption> eval(Iterable<xxx.OpenedInterruption> openedInterruption_, xxx.InterruptionType a1, xxx.InterruptionTargetType a2, com.google.common.base.Present a3) {
        java.util.List<xxx.OpenedInterruption> rv = new java.util.ArrayList<xxx.OpenedInterruption>();
        for (xxx.OpenedInterruption openedInterruption : openedInterruption_) {
            try {
                if (com.mysema.query.collections.CollQueryFunctions.equals(com.mysema.query.collections.CollQueryFunctions.<xxx.InterruptionType>get(openedInterruption, "type"), a1) && com.mysema.query.collections.CollQueryFunctions.equals(com.mysema.query.collections.CollQueryFunctions.<xxx.InterruptionTargetType>get(openedInterruption, "targetType"), a2) && com.mysema.query.collections.CollQueryFunctions.equals(com.mysema.query.collections.CollQueryFunctions.<com.google.common.base.Optional>get(openedInterruption, "target"), a3)) {
                    rv.add(openedInterruption);
                }
            } catch (NullPointerException npe) { }
        }
        return rv;    }

}

failed.
        /Q_01363784216_1275614662_1275614662_1573163836_01698119955_566403833.java:3: error: Present is not public in com.google.common.base; cannot be accessed from outside package
public static Iterable<xxx.OpenedInterruption> eval(Iterable<xxx.OpenedInterruption> openedInterruption_, xxx.InterruptionType a1, xxx.InterruptionTargetType a2, com.google.common.base.Present a3) {
        ^
        1 error

        at com.mysema.codegen.JDKEvaluatorFactory.compile(JDKEvaluatorFactory.java:74)
        at com.mysema.codegen.AbstractEvaluatorFactory.createEvaluator(AbstractEvaluatorFactory.java:128)
        at com.mysema.query.collections.DefaultEvaluatorFactory.createEvaluator(DefaultEvaluatorFactory.java:157)
        at com.mysema.query.collections.DefaultQueryEngine.evaluateSingleSource(DefaultQueryEngine.java:176)
        at com.mysema.query.collections.DefaultQueryEngine.list(DefaultQueryEngine.java:91)
        at com.mysema.query.collections.AbstractCollQuery.list(AbstractCollQuery.java:219)
        at xxx.BusinessInterruptionServiceImplTest$MockedQuery.list(BusinessInterruptionServiceImplTest.java:143)
        at xxx.BusinessInterruptionServiceImplTest.setup(BusinessInterruptionServiceImplTest.java:79)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
        at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
        at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
        at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
        at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
        at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
com.mysema.codegen.CodegenException:公共类Q_01363784216_1275614662_1275614662_1573163836_01698119955_566403833的编译{
公共静态Iterable eval(Iterable openedInterruption_u2;,xxx.InterruptionType a1,xxx.InterruptionTargetType a2,com.google.common.base.Present a3){
java.util.List rv=new java.util.ArrayList();
for(xxx.openedintruption openedintruption:openedintruption){
试一试{
if(com.mysema.query.collections.CollQueryFunctions.equals(com.mysema.query.collections.CollQueryFunctions.get(openedInterruption,“type”),a1)和&com.mysema.query.collections.CollQueryFunctions.equals(com.mysema.query.collections.CollQueryFunctions.get(openedInterruption,“targetType”),a2)&&com.mysema.query.collections.CollQueryFunctions.equals(com.mysema.query.collections.CollQueryFunctions.get(openedInterruption,“target”),a3)){
rv.添加(开启中断);
}
}捕获(NullPointerException npe){}
}
返回rv;}
}
失败。
/Q_01363784216_1275614662_1275614662_15731638336_01698119955_566403833.java:3:错误:com.google.common.base中的Present不是公共的;无法从包外部访问
公共静态Iterable eval(Iterable openedInterruption_u2;,xxx.InterruptionType a1,xxx.InterruptionTargetType a2,com.google.common.base.Present a3){
^
1错误
在com.mysema.codegen.JDKEvaluatorFactory.compile上(JDKEvaluatorFactory.java:74)
位于com.mysema.codegen.AbstractEvaluatorFactory.createEvaluator(AbstractEvaluatorFactory.java:128)
位于com.mysema.query.collections.DefaultEvaluatorFactory.createEvaluator(DefaultEvaluatorFactory.java:157)
在com.mysema.query.collections.DefaultQueryEngine.evaluateSingleSource(DefaultQueryEngine.java:176)上
在com.mysema.query.collections.DefaultQueryEngine.list(DefaultQueryEngine.java:91)上
在com.mysema.query.collections.AbstractCollQuery.list(AbstractCollQuery.java:219)上
位于xxx.BusinessInterruptionServiceImplTest$MockedQuery.list(BusinessInterruptionServiceImplTest.java:143)
在xxx.BusinessInterruptionServiceImplTest.setup(BusinessInterruptionServiceImplTest.java:79)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)中
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:47)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:44)
位于org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:309)
位于org.junit.runner.JUnitCore.run(JUnitCore.java:160)
位于com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
位于com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
位于com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl。
public class MockedQuery<T> implements Query<T> {

    private final Path<T> path;
    private final CollQuery collQuery;

    public MockedQuery(final Path<T> path, final Iterable<T> collection) {
        this.path = path;
        collQuery = from(path, collection);
    }

    @Override
    public boolean exists() {
        return collQuery.exists();
    }

    @Override
    public boolean notExists() {
        return !exists();
    }

    @Override
    public CloseableIterator<T> iterate() {
        return collQuery.iterate(path);
    }

    @Override
    public List<T> list() {
        return collQuery.list(path);
    }

    @Nullable
    @Override
    public T singleResult() {
        return collQuery.singleResult(path);
    }

    @Nullable
    @Override
    public T uniqueResult() {
        return collQuery.uniqueResult(path);
    }

    @Override
    public SearchResults<T> listResults() {
        return collQuery.listResults(path);
    }

    @Override
    public long count() {
        return collQuery.count();
    }

    @Override
    public Query<T> limit(final long limit) {
        collQuery.limit(limit);
        return this;
    }

    @Override
    public Query<T> offset(final long offset) {
        collQuery.offset(offset);
        return this;
    }

    @Override
    public Query<T> restrict(final QueryModifiers modifiers) {
        collQuery.restrict(modifiers);
        return this;
    }

    @Override
    public Query<T> orderBy(final OrderSpecifier<?>... o) {
        collQuery.orderBy(o);
        return this;
    }

    @Override
    public <U> Query<T> set(final ParamExpression<U> param, final U value) {
        collQuery.set(param, value);
        return this;
    }

    @Override
    public Query<T> distinct() {
        collQuery.distinct();
        return this;
    }

    @Override
    public Query<T> where(final Predicate... o) {
        collQuery.where(o);
        return this;
    }
}