-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat : enhance tests #1555
feat : enhance tests #1555
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||
---|---|---|---|---|---|---|---|---|---|---|
@@ -1,120 +1,165 @@ | ||||||||||
package com.example.keysetpagination.services; | ||||||||||
package com.example.keysetpagination.repository; | ||||||||||
|
||||||||||
import static org.assertj.core.api.Assertions.assertThat; | ||||||||||
import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||||||||||
|
||||||||||
import com.example.keysetpagination.common.AbstractIntegrationTest; | ||||||||||
import com.example.keysetpagination.common.ContainersConfig; | ||||||||||
import com.example.keysetpagination.config.JpaAuditConfig; | ||||||||||
import com.example.keysetpagination.entities.Animal; | ||||||||||
import com.example.keysetpagination.model.query.QueryOperator; | ||||||||||
import com.example.keysetpagination.model.query.SearchCriteria; | ||||||||||
import com.example.keysetpagination.repositories.AnimalRepository; | ||||||||||
import com.example.keysetpagination.services.EntitySpecification; | ||||||||||
import jakarta.persistence.EntityManager; | ||||||||||
import jakarta.persistence.PersistenceContext; | ||||||||||
import java.util.List; | ||||||||||
import org.junit.jupiter.api.BeforeEach; | ||||||||||
import org.junit.jupiter.api.BeforeAll; | ||||||||||
import org.junit.jupiter.api.Disabled; | ||||||||||
import org.junit.jupiter.api.Test; | ||||||||||
import org.junit.jupiter.api.TestInstance; | ||||||||||
import org.springframework.beans.factory.annotation.Autowired; | ||||||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; | ||||||||||
import org.springframework.context.annotation.Import; | ||||||||||
import org.springframework.data.jpa.domain.Specification; | ||||||||||
|
||||||||||
class EntitySpecificationIntTest extends AbstractIntegrationTest { | ||||||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS) | ||||||||||
@DataJpaTest | ||||||||||
@Import({ContainersConfig.class, JpaAuditConfig.class}) | ||||||||||
class EntitySpecificationTest { | ||||||||||
|
||||||||||
private EntitySpecification<Animal> entitySpecification; | ||||||||||
|
||||||||||
@PersistenceContext | ||||||||||
private EntityManager entityManager; | ||||||||||
|
||||||||||
@BeforeEach | ||||||||||
@Autowired | ||||||||||
private AnimalRepository animalRepository; | ||||||||||
|
||||||||||
@BeforeAll | ||||||||||
void setUp() { | ||||||||||
entitySpecification = new EntitySpecification<>(entityManager); | ||||||||||
// Add test data | ||||||||||
Animal mammal = new Animal().setName("Lion").setType("Mammal").setHabitat("Savanna"); | ||||||||||
Animal bird = new Animal().setName("Eagle").setType("Bird").setHabitat("Forest"); | ||||||||||
Animal fish = new Animal().setName("Shark").setType("Fish").setHabitat("Ocean"); | ||||||||||
animalRepository.saveAll(List.of(mammal, bird, fish)); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForEQOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.EQ, "type", List.of("Mammal")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForNEOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.NE, "type", List.of("Reptile")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal", "Bird", "Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForLTOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.LT, "id", List.of("5")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal", "Bird", "Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForGTOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.GT, "id", List.of("2")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForGTEOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.GTE, "id", List.of("3")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForLTEOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.LTE, "id", List.of("7")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal", "Bird", "Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForBetweenOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.BETWEEN, "id", List.of("1", "5")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal", "Bird", "Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForINOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.IN, "type", List.of("Mammal", "Bird")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal", "Bird"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForNOTINOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.NOT_IN, "type", List.of("Fish", "Reptile")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal", "Bird"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForLIKEOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.LIKE, "name", List.of("%Lion%")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForCONTAINSOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.CONTAINS, "name", List.of("ar")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForSTARTS_WITHOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.STARTS_WITH, "name", List.of("E")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Bird"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForENDS_WITHOperator() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.ENDS_WITH, "name", List.of("e")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteria), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Bird"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
|
@@ -126,12 +171,25 @@ void shouldBuildSpecificationForANDOperator() { | |||||||||
Specification<Animal> spec = | ||||||||||
entitySpecification.specificationBuilder(List.of(criteria1, criteriaAnd, criteria2), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal"); | ||||||||||
} | ||||||||||
Comment on lines
+174
to
+175
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct the expected result in In the disabled test Apply this diff to correct the assertion: - assertThat(results).isNotEmpty().extracting("type").containsOnly("Mammal");
+ assertThat(results).isNotEmpty().extracting("type").containsOnly("Bird"); 📝 Committable suggestion
Suggested change
|
||||||||||
|
||||||||||
@Test | ||||||||||
void shouldBuildSpecificationForOROperator() { | ||||||||||
SearchCriteria criteriaOr = new SearchCriteria(QueryOperator.OR, "type", List.of("Amphibian", "Fish")); | ||||||||||
Specification<Animal> spec = entitySpecification.specificationBuilder(List.of(criteriaOr), Animal.class); | ||||||||||
assertThat(spec).isNotNull(); | ||||||||||
List<Animal> results = animalRepository.findAll(spec); | ||||||||||
assertThat(results).isNotEmpty().extracting("type").containsOnly("Fish"); | ||||||||||
} | ||||||||||
|
||||||||||
@Test | ||||||||||
void shouldThrowExceptionForInvalidFieldName() { | ||||||||||
SearchCriteria criteria = new SearchCriteria(QueryOperator.EQ, "invalidField", List.of("value")); | ||||||||||
assertThatThrownBy(() -> entitySpecification.specificationBuilder(List.of(criteria), Animal.class)) | ||||||||||
.isInstanceOf(IllegalArgumentException.class) | ||||||||||
.hasMessageContaining( | ||||||||||
"Unable to locate Attribute with the given name [invalidField] on this ManagedType [com.example.keysetpagination.entities.Animal]"); | ||||||||||
} | ||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid using auto-generated IDs in test assertions
Relying on auto-generated IDs like
"id"
in test criteria can lead to flaky tests since IDs may differ across environments or runs. To ensure test reliability, use stable fields with known values, such as"name"
or"type"
, in yourSearchCriteria
.