Junit, Mockito и Querydsl (Mysema) для издевательства над JPAQueryFactory

Я пытаюсь настроить модульный тест для метода приложения Spring Boot, использующего библиотеку Querydsl (Mysema). Тестируемый метод включает следующие строки кода:

JPAQueryFactory queryFactory = new JPAQueryFactory(em);
QEntity q = QEntity.entity;

long count = queryFactory.from(q)
    .select(q.anInteger)
    .where(aBooleanExpression)
    .fetchCount();

В классе модульного теста я пишу метод настройки, аннотированный @Before, где я делаю следующее:

    JPAQueryFactory queryFactory = Mockito.mock(JPAQueryFactory.class, Mockito.RETURNS_DEEP_STUBS);

    QEntity q = QEntity.etity;
    BooleanExpression aBooleanExpression = ... // The same as used in the method under test

    Mockito
        .when(((JPAQuery<Integer>) queryFactory
                .from(q)
                .select(q.anInteger))
                .where(aBooleanExpression)
                .fetchCount()
        ).thenReturn(1L);

Нет ошибок компиляции, но когда я запускаю тест, получаю исключение:

java.lang.ClassCastException: com.querydsl.core.support.QueryBase$$EnhancerByMockitoWithCGLIB$$6824f47d cannot be cast to com.querydsl.jpa.impl.JPAQuery

Я не знаю, каким образом я должен рефрактировать предыдущий код, чтобы он работал.

2 ответа

Каждый объект возврата вызова

queryFactory.from(q)
            .select(q.anInteger))
            .where(aBooleanExpression)
            .fetchCount()

в вашем случае вы должны издеваться шаг за шагом:

 JPAQuery step1 = Mockito.mock(JPAQuery.class);
 Mockito.when(queryFactory.from(q)).thenReturn(step1);
 JPAQuery step2 = Mockito.mock(JPAQuery.class);
 Mockito.when(step1.select(q.anInteger)).thenReturn(step2);
 JPAQuery step3 = Mockito.mock(JPAQuery.class);
 Mockito.when(step2.where(aBooleanExpression)).thenReturn(step3);

... и так далее

Не уверен насчет класса возвращаемого объекта, пожалуйста, проверьте, это пример только для объяснений.

Я столкнулся с этой проблемой с Springboot unitest, мой запрос

      List<TaxiEntity> taxiEntities = queryFactory.selectFrom(qTaxiEntity)
            .innerJoin(qTaxiEntity.callMe, qDriver)
            .where(qTaxiEntity.abcId.eq(abcId))
            .limit(pageable.getPageSize())
            .offset(pageable.getOffset())
            .fetch();

мой модульный тест для издевательства над этим запросом. Он работает успешно

          @Mock
    private JPAQueryFactory queryFactory;

    @Test
    public void testBanana() {
    .....
    JPAQuery jpaQuery = Mockito.mock(JPAQuery.class);
    when(queryFactory.selectFrom(any())).thenReturn(jpaQuery);
    when(jpaQuery.select(any(Expression.class))).thenReturn(jpaQuery);
    when(jpaQuery.innerJoin((EntityPath) any(), any())).thenReturn(jpaQuery);
    when(jpaQuery.where(any(BooleanExpression.class))).thenReturn(jpaQuery);
    when(jpaQuery.limit(anyLong())).thenReturn(jpaQuery);
    when(jpaQuery.offset(anyLong())).thenReturn(jpaQuery);
    when(jpaQuery.fetch()).thenReturn(resultList);
    ....
    }
Другие вопросы по тегам