Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock Projection Result Spring Data JPA

I am using spring data jpa in my spring boot project.

I am firing an JPQL query and using an projection to store the result of query. My Projection :

public interface VeryBasicProjection {
    String getTitle();
    String getUrl();
}

My service calling this projection :

public List<VeryBasicDTO> getLatestData(int limit){

        // Pageable for Limit
        Pageable pageable = new PageRequest(0, limit);

        // Get Data from DB
        List<VeryBasicProjection> latestData = tableRepository.getLatestData("live", 2,pageable);
        List<VeryBasicDTO> responseDTO = new ArrayList<>();

        // Map Projection to DTO
        for(VeryBasicProjection veryBasicProjection : latestData){
            VeryBasicDTO veryBasicDTO = new VeryBasicDTO();
            veryBasicDTO.buildDTO(veryBasicProjection);
            responseDTO.add(veryBasicDTO);
        }

        return responseDTO;
    }

Now i want to test this service using Mockito(Unit Test Case) I am mocking the call to repository using when and thenReturn.

My question is how do I mock the result of repository? What should be in thenReturn? I mean how do I create instance of projection and setData to it?

like image 690
Ankit Bansal Avatar asked Nov 13 '17 06:11

Ankit Bansal


People also ask

What is projection in spring data JPA?

Projection is one of the first things you’re probably thinking about when implementing a query with Spring Data JPA. This is because projection defines the entity attributes and the database columns returned by your query. So, selecting the right columns is important for your business logic.

How to choose the right projection for your JPA query?

In addition, you need to choose a projection that keeps the overhead as low as possible and provides the data in an easy to use structure. Based on JPA’s query capabilities, Spring Data JPA gives you several options for defining your use case’s perfect projection.

Why does spring data JPA fail to mock a bean?

You're not mocking PersonServiceso it makes sense that it would fail this assertion. Another issue is that Spring Data JPA will also create a bean called personRepository. So your mocked repository bean will be ignored unless you change its name:

What is the return type of query method in spring data JPA?

This interface will be the return type of query method we write in Spring Data JPA’s Repository interface. In Close Projection, the getter methods of interface match exactly with the getter methods of Entity’s properties. Looking at the Book Entity, we can see it has many properties, yet not all of them are helpful.


Video Answer


2 Answers

If you want to create an instance of your projection without creating a class implementing the interface, you can use SpelAwareProxyProjectionFactory.

import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;

...
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
VeryBasicProjection projection = factory.createProjection(VeryBasicProjection.class);
projection.setTitle("theTitle");
projection.setUrl("theUrl");

You also need to add setters in your projection:

public interface VeryBasicProjection {
    String getTitle();
    String getUrl();
    void setTitle(String title);
    void setUrl(String url);
}

Source: https://github.com/spring-projects/spring-data-examples/blob/master/rest/projections/src/test/java/example/springdata/rest/projections/SimpleProjectionTests.java

like image 138
Nis Avatar answered Jan 18 '23 10:01

Nis


This is the simplest way to mock projections in TEST

VeryBasicProjection VeryBasicProjection = new VeryBasicProjection() {
   String getTitle() {
    return "Title";
   }

    String getUrl() {
      return "url";
    }
}
like image 23
IZI_SL Avatar answered Jan 18 '23 11:01

IZI_SL