liveBook · Manning

@DataR2dbcTest

As explained in Spring in Action, Sixth Edition

@DataR2dbcTest is a Spring Boot test annotation that configures an application context with Spring Data R2DBC components for repository integration testing.

Put @DataR2dbcTest on a test class when you want to test Spring Data R2DBC repositories. Spring creates an application context containing the generated repositories as beans, so the test can inject them with @Autowired. StepVerifier can then check the values those repositories emit. section 13.1.3

Test a repository

An IngredientRepository test first deletes existing ingredients, saves three test ingredients, and uses StepVerifier to confirm the save completes with the expected results. Another check collects the results of findAll() and compares them with the expected ingredients. A final check calls findBySlug("FLTO") and verifies the emitted flour-tortilla ingredient. section 13.1.3

Listing 13.7 Testing a Spring Data R2DBC repository
package tacos.data;
 
import static org.assertj.core.api.Assertions.assertThat;
 
import java.util.ArrayList;
 
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.data.r2dbc.DataR2dbcTest;
 
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import tacos.Ingredient;
import tacos.Ingredient.Type;
 
@DataR2dbcTest
public class IngredientRepositoryTest {
 
  @Autowired
  IngredientRepository ingredientRepo;
  
  @BeforeEach
  public void setup() {
      Flux<Ingredient> deleteAndInsert = ingredientRepo.deleteAll()
          .thenMany(ingredientRepo.saveAll(
              Flux.just(
                  new Ingredient("FLTO", "Flour Tortilla", Type.WRAP),
                  new Ingredient("GRBF", "Ground Beef", Type.PROTEIN),
                  new Ingredient("CHED", "Cheddar Cheese", Type.CHEESE)
           )));
      
      StepVerifier.create(deleteAndInsert)
                  .expectNextCount(3)
                  .verifyComplete();
  }
  
  @Test
  public void shouldSaveAndFetchIngredients() {
      
      StepVerifier.create(ingredientRepo.findAll())
          .recordWith(ArrayList::new)
          .thenConsumeWhile(x -> true)
          .consumeRecordedWith(ingredients -> {
            assertThat(ingredients).hasSize(3);
            assertThat(ingredients).contains(
                new Ingredient("FLTO", "Flour Tortilla", Type.WRAP));
            assertThat(ingredients).contains(
                new Ingredient("GRBF", "Ground Beef", Type.PROTEIN));
            assertThat(ingredients).contains(
                new Ingredient("CHED", "Cheddar Cheese", Type.CHEESE));
          })
          .verifyComplete();
      
      StepVerifier.create(ingredientRepo.findBySlug("FLTO"))
          .assertNext(ingredient -> {
              ingredient.equals(new Ingredient("FLTO", "Flour Tortilla", Type.WRAP));
          });
  }
  
}

The test listing shows @DataR2dbcTest on the class, an injected repository, and a setup method that prepares data through reactive repository calls. section 13.1.3

The annotation also works for a service test that uses repositories: inject the repositories, construct the service in setup(), and test its behavior. In a multimodule project, @DataR2dbcTest may not find the application's bootstrap class. Supply a configuration class annotated with @SpringBootConfiguration and @EnableAutoConfiguration so the context can create the repository implementations. If tests sharing an IDE's JVM and contexts interfere through the in-memory H2 database, @DirtiesContext resets the context between runs. section 13.1.4 section 13.1.4

package tacos;
 
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
 
@SpringBootConfiguration
@EnableAutoConfiguration
public class TestConfig {
 
}

This small TestConfig supplies the two annotations needed for the multimodule test configuration. section 13.1.4

How Spring in Action, Sixth Edition covers it

How deep it goes
Shows annotated test classes, repository injection, reactive assertions, and multimodule configuration without examining the annotation's implementation.
Examples
Tests ingredient saves and lookups, then tests an aggregate service built from injected repositories.
What it assumes
Assumes repository types and reactive publishers; explains the extra configuration needed when a multimodule test cannot find the bootstrap class.
What you can do after
Apply it via Spring Boot to inject reactive repositories into tests and verify their results with StepVerifier.
How it connects
Connects Spring Data R2DBC repositories with application contexts, autoconfiguration, StepVerifier, and @DirtiesContext.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Spring in Action, Sixth Edition. The section links point to the parts of the book it draws on.