테스트를 위해 외부 연동부분을 Stup이나 Mock으로 대체할 수 있다.
public class AddressRetriever {
private Http http;
public AddressRetriever(Http http) {
this.http = http;
}
public Address retrieve(double latitude, double longitude)
throws IOException, ParseException {
String parms = String.format("lat=%.6flon=%.6f", latitude, longitude);
String response = http.get(
"http://open.mapquestapi.com/nominatim/v1/reverse?format=json&"
+ parms);
JSONObject obj = (JSONObject)new JSONParser().parse(response);
// ...
}
위와 같은 AddressRetriever 클래스의 retrieve 메서드를 테스트하고 싶은데, http.get 외부 호출을 Mock처리하고 싶다.
아래와 같이 Mockito를 이용해서 when ~ thenReturn구문으로 사전에 행도을 정의하고 생성자에 넣어줄 수 있다.
public class AddressRetrieverTest2 {
@Test
public void answersAppropriateAddressForValidCoordinates()
throws IOException, ParseException {
Http http = mock(Http.class);
when(http.get(contains("lat=38.000000&lon=-104.000000"))).thenReturn(
"{\"address\":{"
+ "\"house_number\":\"324\","
// ...
+ "\"road\":\"North Tejon Street\","
+ "\"city\":\"Colorado Springs\","
+ "\"state\":\"Colorado\","
+ "\"postcode\":\"80903\","
+ "\"country_code\":\"us\"}"
+ "}");
AddressRetriever retriever = new AddressRetriever(http);
Address address = retriever.retrieve(38.0,-104.0);
생성자로 주입할 수 없는 환경이면 아래와 같이 할 수 도 있다.
public class AddressRetriever {
private Http http = new HttpImpl();
public Address retrieve(double latitude, double longitude)
throws IOException, ParseException {
String parms = String.format("lat=%.6f&lon=%.6f", latitude, longitude);
String response = http.get(
"http://open.mapquestapi.com/nominatim/v1/reverse?format=json&"
+ parms);
JSONObject obj = (JSONObject)new JSONParser().parse(response);
// ...
위와 같이 생성자로 주입이 불가능하면 @Mock으로 Mock객체를 정의하고, MockitoAnnotations.initMocks(this) 로 @InjectMocks 붙은 필드(AddressRetriever)를 가져와서 목객체를 거기에 주입한다.
public class AddressRetrieverTest {
@Mock private Http http;
@InjectMocks private AddressRetriever retriever;
@Before
public void createRetriever() {
retriever = new AddressRetriever();
MockitoAnnotations.initMocks(this);
}
@Test
public void answersAppropriateAddressForValidCoordinates()
throws IOException, ParseException {
when(http.get(contains("lat=38.000000&lon=-104.000000")))
.thenReturn("{\"address\":{"
+ "\"house_number\":\"324\","
// ...
+ "\"country_code\":\"us\"}"
+ "}");
Address address = retriever.retrieve(38.0,-104.0);
반응형