How to write a unit test for spring specification?

10,981
  1. if you must test actual code that talks to the DB, use DBUnit for making your life easier, and it is recommended that you use HSQLDB, so that your tests will be able to setup their environment on runtime, without requiring a database already being installed and configured. Inside integration test you check that query is : correct , executable , return expected result , data model is valid...... You don't need to check all possible combination inside integration tests, check only correct execution and result as expected.

  2. if you don't have to talk with the DB (appendOr,appendAnd - you check behavior , not data. check that specification builder has expected behavior - apply AND , OR..... predicates ), use a general mocking library : EasyMock, Mockito or any other, and make the tests not really talk to a DB, which will usually make tests faster and simpler.

so , if you want to 'test only logic, how OR and AND clauses are created' you can use mock for checking way of creation, but you should have min one integration test for method : Specification build() with maximum amount of criteria like appendOr , appendAnd ....

Just for example : here is for example how spring-data tests code :

unit test with use mock : https://github.com/spring-projects/spring-data-jpa/blob/master/src/test/java/org/springframework/data/jpa/repository/query/SimpleJpaQueryUnitTests.java

and integration test : https://github.com/spring-projects/spring-data-jpa/blob/master/src/test/java/org/springframework/data/jpa/repository/query/JpaCountQueryCreatorIntegrationTests.java

there are two type of test and whey dedicated for different cases.

Share:
10,981
ByeBye
Author by

ByeBye

Java enthusiast.

Updated on June 04, 2022

Comments

  • ByeBye
    ByeBye almost 2 years

    I created a builder class which construct Specifications object. It is used for creating queries for JpaSpecificationExecutor. The builder is used, because I have many parameters which can be null/empty (comes from user for filtering) and I cannot use just Specifications without it:

    public class SpecificationBuilder<T> {
    
        private Specifications<T> specification;
    
        public SpecificationBuilder() {
    
        }
    
        public SpecificationBuilder(final Specification<T> spec) {
            specification = Specifications.where(spec);
        }
    
        public SpecificationBuilder<T> appendOr(final Specification<T> spec) {
            specification = Specifications.where(spec).or(specification);
            return this;
        }
    
        public SpecificationBuilder<T> appendAnd(final Specification<T> spec) {
            specification = Specifications.where(spec).and(specification);
            return this;
        }
    
        public Specification<T> build() {
            return Specifications.where(specification);
        }
    
    }
    

    My problem here is that I don't know how to test it in isolation. Of course I can autowire real repository (on in-memory db) but I want to not involve any other classes for that and test only logic, how OR and AND clauses are created.

    Unfortunately in spring API I cannot find any method which will help