Guava Supplier Mock Datetimeの使用


詳細
以下の例でGuava Supplierの使い方を理解する.ユニットテストを行うときは、Mockが外部リソースへの依存を解消する必要があるかもしれません.例えば、時間、乱数、システムファイルアクセス.
テストするコードを次に示します.現在の時刻を出力します.

@Controller
@RequestMapping(value = "/time")
@VisibleForTesting
class TimeController {
 
	@RequestMapping(value = "/current", method = RequestMethod.GET)
	@ResponseBody
	public String showCurrentTime() {
		// BAD!!! Can't test
		DateTime dateTime = new DateTime();
		return DateTimeFormat.forPattern("hh:mm").print(dateTime);
	}
}

しかし、ここでは、コードの中で直接newのDateTimeオブジェクトであるため、システム時間への直接的な依存をもたらすという問題がある.出力時間のテストが困難になるため、ここではGuava Supplierを借ります.
Supplierにはget()という方法しかありません.suppilerが構築したオブジェクトを返します.たとえば、次の例です.

public class FirstNameSupplier implements Supplier {
 
	private String value;
	private static final String DEFAULT_NAME = "GUEST";
	 
	public FirstNameSupplier() {
		// Just believe that this goes and gets a User from somewhere
		String firstName = UserUtilities.getUser().getFirstName();
		// more Guava
		if(isNullOrEmpty(firstName)) {
			value = DEFAULT_NAME;
		} else {
			value = firstName;
		}
	}
	 
	@Override
	public String get() {
		return value;
	}
}

上のコードではfirstNameが何であるかは気にしないで、getメソッドを呼び出すだけでいいです.
ターゲットコードの再構築
DateTime Supplierを実現同時に1つのインタフェースを提供して、テストを便利にします:

public interface DateTimeSupplier extends Supplier {
	DateTime get();
}

具体的には

public class DateTimeUTCSupplier implements DateTimeSupplier {
	@Override
	public DateTime get() {
		return new DateTime(DateTimeZone.UTC);
	}
}

DateTimeSupplierに注入します
@Controller
@RequestMapping(value = "/time")
@VisibleForTesting
class TimeController {
 
	@Autowired
	@VisibleForTesting
	// Injected DateTimeSupplier
	DateTimeSupplier dateTime;
	 
	@RequestMapping(value = "/current", method = RequestMethod.GET)
	@ResponseBody
	public String showCurrentTime() {
		return DateTimeFormat.forPattern("hh:mm").print(dateTime.get());
	}
}

テスト用のMockDateTimeSupplierを作成します.

public class MockDateTimeSupplier implements DateTimeSupplier {
 
	private final DateTime mockedDateTime;
	 
		public MockDateTimeSupplier(DateTime mockedDateTime) {
		this.mockedDateTime = mockedDateTime;
	}
	 
	@Override
	public DateTime get() {
		return mockedDateTime;
	}
}

最後にテストコード:
public class TimeControllerTest {
 
	private final int HOUR_OF_DAY = 12;
	private final int MINUTE_OF_DAY = 30;
	 
	@Test
	public void testShowCurrentTime() throws Exception {
		TimeController controller = new TimeController();
		// Create the mock DateTimeSupplier with our known DateTime
		controller.dateTime = new MockDateTimeSupplier(new DateTime(2012, 1, 1, HOUR_OF_DAY, MINUTE_OF_DAY, 0, 0));
		 
		// Call our method
		String dateTimeString = controller.showCurrentTime();
		 
		// Using hamcrest for easier to read assertions and condition matchers
		assertThat(dateTimeString, is(String.format("%d:%d", HOUR_OF_DAY, MINUTE_OF_DAY)));
}
 
}

全体的な感覚コードはやはり比較的に多くて、またインタフェースはまた実現したのです.目標はシステム時間に対してmockを行うことであるが、ユニットテストの構想を提供した.
原文:http://java.dzone.com/articles/mocking-jodatimes-datetime-and