Smriti mool
Smriti mool

Reputation: 139

How to test native queries in Spring Boot application?

I am completely new in coding by following TDD approach. Now, I'm not sure whether every code needs test case, before it is written. How do I test native queries with if-else conditions?

I've researched some of the ways like following but didn't satisfy my question though:

Testing a Spring Boot application?

https://stackoverflow.com/search?q=test+entitymanager

https://stackoverflow.com/search?q=entitymanager+returned+null+in+testing

JUnit test if else case

@Transactional
public class ProfileRepositoryCustomImpl implements ProfileRepositoryCustom {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List<ProfileMinimalResponseDTO> searchProfile(ProfileDTO profileDTO) {

        Query query = entityManager.createNativeQuery(QueryCreator.createQueryToSearchProfile.apply(profileDTO));

        List<Object[]> list = query.getResultList();

        if (ObjectUtils.isEmpty(list))
            throw new NoContentFoundException(NoRecordsFound.MESSAGE, NoRecordsFound.DEVELOPER_MESSAGE);

        return list.stream().map(
                ProfileUtils.convertObjectToProfileResponseDTO)
                .collect(Collectors.toList());
    }
}

Entity looks like:

@Entity
@Table(name = "profile")
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
public class Profile implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "description")
    private String description;

    @Column(name = "status")
    private Character status;

    @Column(name = "department_id")
    private Long departmentId;

    @Column(name = "sub_department_id")
    private Long subDepartmentId;

}

public class QueryCreator {

    public static Function<ProfileDTO, String> createQueryToSearchProfile = (profileDTO -> {
        String query = "";

        query += " SELECT" +
                " p.id," +                          //[0]
                " p.name," +                        //[1]
                " p.status," +                      //[2]
                " p.department_id," +               //[3]
                " p.sub_department_id" +            //[4]
                " FROM" +
                " profile p" +
                " WHERE p.id!=0";

        if (!Objects.isNull(profileDTO)) {
            if (!Objects.isNull(profileDTO.getName()))
                query += " AND p.name='" + profileDTO.getName() + "'";

            if (!Objects.isNull(profileDTO.getDepartmentId()))
                query += " AND p.department_id=" + profileDTO.getDepartmentId();

            if (!Objects.isNull(profileDTO.getSubDepartmentId()))
                query += " AND p.sub_department_id=" + profileDTO.getDepartmentId();
        }

        return query;
    });

}

 public static Function<Object[], ProfileMinimalResponseDTO> convertObjectToProfileResponseDTO = (objects) -> {

        final Integer ID = 0;
        final Integer NAME = 1;
        final Integer STATUS = 2;
        final Integer DEPARTMENT_ID = 3;
        final Integer SUB_DEPARTMENT_ID = 4;

        return ProfileMinimalResponseDTO.builder()
                .id(Long.parseLong(objects[ID].toString()))
                .name(objects[NAME].toString())
                .status(objects[STATUS].toString().charAt(0))
                .departmentId(Long.parseLong(objects[DEPARTMENT_ID].toString()))
                .subDepartmentId(Long.parseLong(objects[SUB_DEPARTMENT_ID].toString()))
                .build();
    };

I am expecting answers on how to write test case for above scenerio. Also, any references to learning TDD would be very kind and helpful.

Upvotes: 2

Views: 3104

Answers (1)

mate00
mate00

Reputation: 2955

regarding references for learning TDD I would definitely recommend a classic book, Kent Beck's "TDD by example": https://www.amazon.co.uk/Test-Driven-Development-Addison-Wesley-Signature/dp/0321146530

One approach would be to use some in-memory database (H2 being a natural choice in case of Spring Boot). You could then create schema.sql and data.sql scripts to insert specific data to test your corner cases.

Another option is to use Mockito to mock EntityManager and Query objects. You then don't need to create SQL with inserts and 'create tables', but you prepare a set of objects manually which will be returned by these mocks.

Hope this helps. Let me know if you want me to elaborate on this a bit.

Upvotes: 1

Related Questions