Εμφάνιση αναρτήσεων με ετικέτα @DataJpaTest. Εμφάνιση όλων των αναρτήσεων
Εμφάνιση αναρτήσεων με ετικέτα @DataJpaTest. Εμφάνιση όλων των αναρτήσεων

Σάββατο 23 Οκτωβρίου 2021

Spring Certification: Spring Boot Testing

When do you want to use @SpringBootTest annotation?
  • When we want to load whole ApplicationContext for our tests
  • Mostly when running a JUnit integration test
  • @SpringBootTest will search for a main configuration class or @SpringBootApplication annotated class upwards the project structure tree, and start a Spring application on a mock or running environment, with full application context - no slicing.
  • To use it:
    • JUnit 4 - Add @RunWith(SpringRunner.class) also
    • JUnit 5 - Runner is already included in the annotation

What does @SpringBootTest auto-configure?
  • @SpringBootTest  searches for  @SpringBootApplication / @SpringBootConfiguration, which contains @EnableAutoConfiguration, which triggers Spring AutoConfiguration mechanism.

  • So it uses all xxxAutoConfiguration classes in spring.factories, which autoconfigure all beans needed, according to what exists in the classpath

  • Alternatively, @SpringBootTest(classes = CustomApplication.class) sets a specific main configuration class

  • Also, @SpringBootTest(properties = "spring.main.web-application-type=reactive") takes in account specific properties file



What dependencies does spring-boot-starter-test brings to the classpath?
  • Spring Test
  • Spring Boot Test modules
  • JSONPath
  • JUnit,
  • AssertJ
  • Mockito
  • Hamcrest
  • JSONassert


How do you perform integration testing with @SpringBootTest for a web application?
  • Integration tests should be performed in a full running server environment, so we use:
    • @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) (or defined port)
    • And a fully configured TestRestTemplate or WebTestClient to act a REST client for our tests 
  • Integration tests could be run in a mock servlet environment, that by default @SpringBootTest bootstraps. The original application context will be loaded. For actual test methods, we will use MockMvc. Generally, note that there are no actual mocks of any classes. Also we don't need to use @MockBean or mocks like in @WebMvcTest 




  • Additionally, we might need a test-only property file, so we use @TestPropertySource. As mentioned, the @Value annotations will now be injected from our test property file.



When do you want to use @WebMvcTest? What does it auto-configure?
  • When we want to test the web slice of an application, particularly the behavior of the controllers interacting with the outer world.
  • By default, it autoconfigures all Spring beans referring to the web part, and specifically:
    • @Controller
    • @ControllerAdvice
    • @JsonComponent
    • @WebMvcConfigurer
    • and more
  • Can autoconfigure specific controller with: @WebMvcTest(SomeController.class)
  • Except for @Controllers setup, we must mock their dependencies with use of @MockBean
  • Autoconfigures MockMvc, to use in performing mock web tests



Differences between @SpringBootTest, MockMvc, @WebMvcTest





What are the differences between @MockBean and @Mock?
  • @Mock  is used to create mocks of any class, generally method-wise, while @MockBean to replace Spring bean context-wise
  • @Mock needs @RunWith(MockitoJUnitRunner.class) (Mockito library), while @MockBean needs @RunWith(SpringRunner.class) (spring-boot-test)
  • @Mock creates a Mockito mock, while @MockBean creates a Mockito mock and injects it into the Application Context
  • In order for a @Mock to be injected in its container class, need to use @InjectMocks on container class reference


When do you want @DataJpaTest for? What does it auto-configure?
  • Use for test slicing, particularly for testing of Spring beans that talk to a database (Entities, Repositories)
  • Configures in-memory database for testing
  • Loads in Application Context: @Entities, @Repositories, @TestEntityManager

Τρίτη 5 Οκτωβρίου 2021

Spring Certification: Spring Data JPA

What is a Spring Data Repository interface?
  • Spring Data Repositories are implementations of the DAO pattern
  • Spring Data provides: CrudRepository, JpaRepository, and PagingAndSortingRepository
  • We can extend these by defining our Entity: 
  • @Repository
    public interface DayActivityRepository extends JpaRepository<DayActivity, Long> {...}
  • And thus define the DAO pattern as an one-to-one relationship of an Entity with a Repository
  • In runtime, Spring's Data Access layer will implement automatically the above, using also the out-of-the-box EntityManager to perform crud operations.

How do you define a Spring Data Repository interface? Why is it an interface not a class?

  • Define a domain class-specific repository interface (e.g. DayActivityRepository) that extends Repository and is typed to the domain class (e.g. DayActivity) and an ID type. 
  • To expose CRUD methods for that domain type:  extend CrudRepository
  • To enable paging/sorting capabilities: extend PagingAndSortingRepository
  • To enable flushing the persistence context and deleting records in a batch: extend JpaRepository

  • It is an interface in order for Spring to create a JDK dynamic proxy for it, and fully implement it in runtime. Additionally, facilitates the use of generic parameter for our Entity. 


What is the naming convention for finder methods in a Spring Data Repository interface?
  • FIND | limit/top/distinct | BY | field(s) conditional expression | comparison | order expression
  • Example: findTop3ByNameOrSurnameContainsOrderByName ("searchTerm")


How are Spring Data repositories implemented by Spring at runtime?
  • Α JDK proxy (created from Spring's ProxyFactory API), and a QueryExecutorMethodInterceptor intercept all client calls to our @Repository, and then route usually to SimpleJpaRepository base class, which has implementations of defined methods
  • Additionally, @EnableJpaRepositories scans all @Repositories and creates Spring Beans, backed by default implementations of SimpleJpaRepository

What is @Query used for?
  • Define @Query on top of finder methods, in order to bypass call to these implementations, and act according to inner JPQL query

How to configure JPA with Spring Boot's Spring Data JPA ?
  • Pom dependencies:
    • spring-boot-starter (autoconfiguration)
    • spring-boot-starter-data-jpa (JPA Repositories hierarchy, hibernate core)
  • EntityManager factory:
    • Already provided with Hibernate as JPA provider
  • Datasource:
    • Auto-configured according to DB dependency in pom, and application properties (username, password, url, etc..)

Τετάρτη 28 Απριλίου 2021

Spring Boot @DataJpaTest with simple @Repository stereotype and JdbcTemplate



Spring Boot @DataJpaTest with simple @Repository stereotype







1. DAO implementation with JdbcTemplate

@Repository public class UspNeighboursDAOImpl implements UspNeighboursDAO { @Autowired private JdbcTemplate jdbcTemplate; final String SELECT_QUERY = "select * from usp_neighbours where usp_id = ?"; @Override public List<Map<String, Object>> getNeighboursByUspId(int uspId) { return jdbcTemplate.queryForList(SELECT_QUERY, uspId); } } // DAO Interface public interface UspNeighboursDAO { List<Map<String, Object>> getNeighboursByUspId(int uspId); }


2. Testing

@DataJpaTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class ApplicationTests { @Autowired private UspNeighboursDAO uspNeighboursDAO; @Test public void testNeighbours1() { List<?> resList = uspNeighboursDAO.getNeighboursByUspId(2); assertEquals(resList.size(), 2); } }