職場では、テスト駆動開発を可能な限り実践しています。私がよく遭遇することの 1 つは、多数の DTO をセットアップしなければならないことです。これらの構造が少し複雑な場合、これは非常に多くのコードになります。これに関する問題は、コードがかなり反復的であることが多く、テストの主な目的から気を散らしているように感じることです。たとえば、少し不自然で凝縮された例 (Java、jUnit + mockito) を使用すると、次のようになります。
class BookingServiceTest {
private final static int HOUR_IN_MILLIS = 60 * 60 * 1000;
private final static int LOCATION_ID = 1;
@Mock
private BookingLocationDao bookingLocationDao;
@InjectMocks
private BookingService service = new BookingService();
@Test
public void yieldsAWarningWhenABookingOverlapsAnotherInTheSameLocation() {
// This part is a bit repetetive over many tests:
Date now = new Date()
Location location = new Location()
location.setId(LOCATION_ID);
Booking existingBooking = new Booking()
existingBooking.setStart(now);
existingBooking.setDuration(HOUR_IN_MILLIS);
existingBooking.setLocation(location);
// To here
when(bookingLocationDao.findBookingsAtLocation(LOCATION_ID))
.thenReturn(Arrays.asList(existingBooking));
// Then again setting up a booking :\
Booking newBooking = new Booking();
newBooking.setStart(now);
newBooking.setDuration(HOUR_IN_MILLIS / 2);
newBooking.setLocation(location);
// Actual test...
BookingResult result = service.book(newBooking);
assertThat(result.getWarnings(), hasSize(1));
assertThat(result.getWarnings().get(0).getType(), is(BookingWarningType.OVERLAPING_BOOKING));
}
}
この例では、セットアップはそれほど複雑ではないので、あまり考えません。ただし、より複雑な入力が必要な場合は、メソッドへの入力をセットアップするためのコードが大きくなる傾向があります。いくつかのテストで同様の入力が使用されると、問題は悪化します。セットアップ コードを別の TestUtil クラスにリファクタリングすると、少しは役に立ちます。問題は、数か月後に新しいテストを作成するときに、これらのユーティリティ クラスを見つけるのが少し難しく、重複が発生することです。
- テストセットアップでコードの重複を最小限に抑えるために、この種の「複雑な」DTO を処理する良い方法は何ですか?
- 同様のコードを操作するときに、抽出された TestUtilities が確実に見つかるようにするにはどうすればよいですか?
- 私はそれを間違っていますか?:) この状況を完全に回避するには、ソフトウェアを別の方法で構築する必要がありますか? もしそうなら、どのように?