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

Σάββατο 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

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

Spring Certification: Testing

What type of tests typically use Spring?
  • Unit testing
  • Integration testing

How can you create a shared application context in a JUnit integration test?
  • Enable Spring TestContext Framework to load shared application context, using below JUnit runner:
  • @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = OrderConfiguration.class)
    public class OrderServiceTests implements ApplicationContextAware { }

  • Variation of above:
  • @ContextConfiguration(classes = OrderConfiguration.class)

    public class OrderServiceTests implements ApplicationContextAware extends AbstractJUnit4SpringContextTests { }

  • Use @DirtiesContext to re-create context for next tests


When and where do you use @Transactional in testing?
  • Method level:
    • @Transactional - Method runs in own transaction rollbacked at the end by default
    • To override above, use @TransactionConfiguration(defaultRollback = false) in class level
  • Class level:
    • @Transactional - All methods run in own transaction rollbacked at the end by default
    • To override above, use @Rollback(false) or @Commit in desired method


How are mock frameworks such as Mockito or EasyMock used?
  • Declare the mock:
    • OrderBook mockOrderBook = mock(OrderBook.class);
    • Or using annotation @Mock:
      • Use @RunWith(MockitoJUnitRunner.class) in class method
      • Or MockitoAnnotations.initMocks(this) in before / setup method
    • Or (Spring Boot), use @MockBean which mocks Spring beans
  • Inject mock in related component
  • Set behaviour when called:
  • when(mockOrderBook.findAllForBook()).thenReturn(books);
  • Test and verify with Assertions

How is @ContextConfiguration used?
  • In Spring, it's used for loading an ApplicationContext, along with a JUnit runner
  • Example 1: 
    • @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(classes={BookConfig.class})
      public class BookConfigTest {}
  • Example 2:
    • @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration
      public class BookConfigTest {}
    • Loads context from BookConfigText-context.xml classpath file

  • In Spring Boot, @SpringBootTest includes @ContextConfiguration annotation


How does Spring Boot simplify writing tests?
  • Adding dependency spring-boot-starter-test provides:
    spring-boot-test, spring-boot-test-autoconfigure     which provide below:


    JUnit: The de-facto standard for unit testing Java applications.
    Spring Test & Spring Boot Test: Utilities and integration test support for Spring Boot applications.
    AssertJ: A fluent assertion library.
    Hamcrest: A library of matcher objects (also known as constraints or predicates).
    Mockito: A Java mocking framework.
    JSONassert: An assertion library for JSON.
    JsonPath: XPath for JSON.

  • Instantiate dependencies by using new or mock, no need to involve Spring

  • Integration testing with Spring ApplicationContext with or without requiring deployment (MockMvc)

  • Spring Boot: Detects automatically test configuration without @ContextConfiguration and declaring @Configuration classes
     Detects classes @SpringBootApplication or @SpringBootConfiguration

  • Spring Boot: Use *Test annotations to introduce test slicing. 
    Example: @DataJpaTest, @WebMvcTest

  • Spring’s test framework caches application contexts between tests.
    Therefore, as long as your tests share the same configuration (no matter how it is discovered),
    the potentially time-consuming process of loading the context happens only once.

  • @TestConfiguration: Can exclude loading automatically configuration classes belonging in src/test/java.
    Then, can decide to @Import or not the specific configuration



What does @SpringBootTest do?
How does it interact with @SpringBootApplication and@SpringBootConfiguration?

  • Used to load a full Application Context, either running a server or in mock environment
  • Includes option to load specific properties

  • SpringBootTest annotation traverses related class package upwards until a @SpringBootConfiguration is located
  • Note that @SpringBootApplication included @SpringBootConfiguration 
  • It then constructs a whole Application Context