Spring BootにおけるRepository層に対する単体テスト
目次
ソース
AddressMapper.java
1 2 | @Select ( "SELECT * FROM address WHERE city_id = #{cityId}" ) Set<Address> findAddress( @Param ( "cityId" ) int cityId); |
複数のデータが返ってくるようなSQLです。
AddressMapperTests.java
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | @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なのか」
1 | assertThat(actual).extracting( "phone" ).allMatch(i -> Arrays.asList( "28303384290" , "635297277345" ).contains(i)); |
「それぞれのオブジェクトの中に何も入ってなければOK」
1 | assertThat(actual).extracting( "address2" ).allMatch(Objects::isNull); |
コメントを書く