Undergoing

Controller Component 작성 - 2 본문

개발/TDD

Controller Component 작성 - 2

Halkrine 2012. 6. 11. 13:22

앞 포스팅에서 DefaultController 클래스를  인스턴트화 하는 부분을 테스트해 볼 것이다. 일단 DefaultController 객체를 생성하고 테스트 작성을 위한 프레임워크를 set-up 한다.


TestDefaultController.java 

public class TestDefaultController {

private DefaultController controller;

@Before

public void instantiate() throws Exception

{

controller = new DefaultController();

}


@Test

public void testMethod()

{

throw new RuntimeException("implement me");

}

}


DefaultController 인스턴스를 만들기 위해 @Before 주석을 이용한다. 또한 테스트할 것이 하나도 없으면 안 되기에 더미 테스트 메서드(testMethod())를 추가한다. 구현이 덜 끝난 테스트 코드는 예외를 보여줘야 하기 때문에 testMethod 클래스 내에 적당한 예외처리를 해둔다. 이는 부트스트랩 테스트 코드로 볼 수 있다.


부트스트랩 테스트가 갖춰졌으니, 이제 첫 번째 테스트 대상을 선정해야 한다. 이 컨트롤러의 목적이 요청을 처리하여 응답을 내주는 것이지만, 앞 코드에서는 요청을 처리하기 전에 일단 RequestHandler가 돌아가므로 이에 대한 테스트를 먼저 해줘야 할 것이다. Request와 함께 담당 RequestHandler를 추가한 후, 동일한 Request를 이용하여 RequestHandler를 얻는다. 그리고 얻어낸 RequestHandler가 앞서 추가했던 것과 같은지 확인하는 작업까지 수행해야 한다.


본격적인 테스트를 위해 테스트 클래스를 집어넣을 곳을 정해야 하는데, 보통 두 가지 방법이 있다.


- 동일 패키지의 public class 로 만들거나 : 클래스가 다양하고 앞으로 복잡해질 것 같을 때

- 테스트 클래스 안에 inner class로 만들거나 : 클래스가 단순하고 앞으로도 복잡해질 것 같지 않을 때


이 코드 자체는 그렇게 복잡하지 않기에 TestDefaultController 클래스 안에 내부 클래스로 작성할 것이다.


TestDefaultController.java -> 내부 클래스로 선언된 테스트 클래스

...

public class TestDefaultController {

private DefaultController controller;

private Request request;

public class SampleRequest implements Request

{

public String getName()

{return "테스트";}

}

private class SampleHandler implements RequestHandler

{

public Response process(Request request) throws Exception

{

return new SampleResponse();

}

}

private class SampleResponse implements Response

{

}

...


먼저 약속된 이름인 "테스트" 를 반환하는 요청 객체를 만든 다음 SampleHandler를 구현한다. 인터페이스를 사용하는 측에서 process 메서드를 호출할 것이니 일단 구현해 둔다. 바로 process를 테스트할 것이 아니기 때문에 SimpleResponse 객체를 반환하도록 하여 시그너처만 만족시키도록 해둔다. 이후에는 빈 SampleResponse를 정의하여 인스턴트화할 것을 준비한다.


* DefaultController 객체는 이미 @Before 메서드에서 인스턴스화 해뒀음을 인지한다.


TestDefaultcontroller.java -> SampleHandler에 대한 테스트 

...

import static org.junit.Assert.*;


public class TestDefaultController

{

...

@Test
public void testAddHandler() // 테스트 객체들을 인스턴스화함

{

Request request = new SampleRequest(); //컨트롤러(테스트 대상 객체)에 테스트 핸들러 추가

RequestHandler handler = new SampleHandler(); //핸들러를 얻어 새 변수에 할당

controller.addHandler(request, handler);

RequestHandler handler2 = controller.getHandler(request);  //앞서 추가했던 핸들러와 동일한지 단언해봄

assertSame("컨트롤러에 세팅한 핸들러는 우리가 얻은 것과 같은 핸들러여야 한다",handler2, handler);

}
... 


이 단위 테스트는 RequestHandler를 저장하고, 찾아내는 메커니즘이 잘 동작한다는 것을 확인할 수 있다. 차후에 addHandler나 getRequest가 오작동하게 될 경우 바로 검출해낼 수 있다.


이제 컨트롤러의 요청을 처리하는 기능을 구현해보자. 


TestDefaultController.java -> DefaultController에 대한 테스트 

...

@Test

public void testProcessRequest()

{

Request request = new SampleRequest();

RequestHandler handler = new SampleHandler();

controller.addHandler(request,handler);

Response response = controller.processRequest(request);

assertNotNull("null 응답을 해서는 안 됩니다", response);

assertEquals("응답은 SampleResponse 타입으로 이루어져야 합니다", SampleResponse.class, response.getClass());


...


- Response response = controller.processRequest(request); : processRequest 호출

- assertNotNull("null 응답을 해서는 안 됩니다", response); : response 객체가 null값인지 검사


여태까지 작성한 소스들을 보면 


Request request = new SampleRequest();

RequestHandler handler = new SampleHandler();

controller.addHandler(request,handler);


이와 같이 중복되는 코드가 있기 때문에 이를 @Before로 옮겨 중복 코드를 줄일 수 있다. 단, 메서드를 합칠 수는 없으니 주의해야 한다.


TestDefaultcontroller -> @Before 추가 및 @Test 변경 

package junit.ch3;


import org.junit.Before; 

import org.junit.Ignore;

import org.junit.Test;

 

import static org.junit.Assert.*;


public class TestDefaultController {

private DefaultController controller;

private Request request;

private RequestHandler handler;

@Before

public void initialize() throws Exception

{

controller = new DefaultController();

request = new SampleRequest();

handler = new SampleHandler();

controller.addHandler(request,handler);

...

@Test

public void testAddHandler()

{

RequestHandler handler2 = controller.getHandler(request);

assertSame("컨트롤러에 세팅한 핸들러는 우리가 얻은 것과 같은 핸들러여야 한다",handler2, handler);

}

@Test

public void testProcessRequest()

{

Response response = controller.processRequest(request);

assertNotNull("null 응답을 해서는 안 됩니다", response);

assertEquals("응답은 SampleResponse 타입으로 이루어져야 합니다", SampleResponse.class, response.getClass());

}



'개발 > TDD' 카테고리의 다른 글

Test Code 작성 규율  (0) 2012.06.27
Controller Component 작성 - 3  (0) 2012.06.11
Controller Component 작성 - 1  (0) 2012.06.11
JUnit의 개요  (0) 2012.06.07