Spring BootにおけるRepository層に対する単体テスト
ソース
AddressMapper.java
@Select("SELECT * FROM address WHERE city_id = #{cityId}") Set<Address> findAddress(@Param("cityId") int cityId);
複数のデータが返ってくるようなSQLです。
AddressMapperTests.java
@MybatisTest public class AddressMapperTests { @Autowired private AddressMapper target; @Autowired private DataSource dataSource; private final Operation RESET_DATA = Operations.deleteAllFrom("address"); private void dbSetup(Operation operation) { Destination destination = new DataSourceDestination(dataSource); DbSetup dbSetup = new DbSetup(destination, operation); dbSetup.launch(); } @BeforeEach void setUp() { dbSetup(Operations.sequenceOf( RESET_DATA )); } @AfterEach void tearDown() { dbSetup(Operations.sequenceOf( RESET_DATA )); } @DisplayName("データ検証テスト") @Nested class FieldValue { private final Operation INSERT_ADDRESS_DATA = Operations.insertInto("address") .columns("address_id", "address", "district", "city_id", "phone", "last_update") .values(1, "fashion 109", "Shibuya", 1, "28303384290", "2012-01-01 12:12:00") .values(2, "salary 999", "Shinbashi", 1, "635297277345", "2012-01-02 12:12:00") .build(); @BeforeEach void setUp() { dbSetup(INSERT_ADDRESS_DATA); } @DisplayName("Setに含まれる要素をまとめて検証する") @Test void dataValueTest() { //GIVEN int cityId = 1; //WHEN Set<Address> actual = target.findAddress(cityId); //THEN assertThat(actual).extracting("addressId").allMatch(i -> Arrays.asList(1, 2).contains(i)); assertThat(actual).extracting("address").allMatch(i -> Arrays.asList("fashion 109", "salary 999").contains(i)); assertThat(actual).extracting("address2").allMatch(Objects::isNull); assertThat(actual).extracting("district").allMatch(i -> Arrays.asList("Shibuya", "Shinbashi").contains(i)); assertThat(actual).extracting("postalCode").allMatch(Objects::isNull); assertThat(actual).extracting("phone").allMatch(i -> Arrays.asList("28303384290", "635297277345").contains(i)); assertThat(actual).extracting("lastUpdate").allMatch(i -> Arrays.asList( LocalDateTime.parse("2012-01-01 12:12:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), LocalDateTime.parse("2012-01-02 12:12:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) ).contains(i)); } } }
解説
解説したいところは2点あります。
@MybatisTest
@MybatisTestを使用することで、MybatisによるSQL実行に必要なコンポーネントのみを読み込んでくれるので、リソースが必要最小限で済みます。
@SpringBootTestでも動くのですが、@SpringBootTestの場合はプロジェクトのコンポーネント全てを読み込んでしまうので、Testに時間がかかります。
Collection型のオブジェクトの中身をまとめて検証する
THENで検証しているところで、Set型のオブジェクトの中身をまとめて検証しています。
List型では順番にfor文でオブジェクトを取り出して値を一つ一つ検証するということも可能ですが、Set型は順序性が担保されていないため、一つ一つ取り出して検証ということが出来ません。
そういった時に「それぞれのオブジェクトの中にどんな値が入っていればOKなのか」を示してあげて、一致すればOKという感じでテストしています。
「それぞれのオブジェクトの中にどんな値が入っていればOKなのか」
assertThat(actual).extracting("phone").allMatch(i -> Arrays.asList("28303384290", "635297277345").contains(i));
「それぞれのオブジェクトの中に何も入ってなければOK」
assertThat(actual).extracting("address2").allMatch(Objects::isNull);
コメントを書く