2012-04-27 3 views
3

TDD의 범위에서 리팩터링을 명확히하고 싶습니다."pretty"JUnit 테스트를 작성하기 위해 리 팩터링하기

전 :

class Somclass{ 
     public void sendMessage(){  
     WebServiceStub stub = new WebServiceStub();  
     ... 
     stub.sendMsg();   
     } 
    } 

후 :

class Somclass{ 
private WebServiceStub stub; 

    public void sendMessage(){ 
    ... 
    if(stub == null){ 
    stub = new WebServiceStub(); 
    } 
    ... 
    stub.sendMsg();   
    } 
} 

그래서 내가 sendMsg() 메소드를 확인하고 일부는 결과를 주장 만들고 싶어. 이 스텁을 모방 할 확실성을 가지려면이 스텁 로컬 변수를 인스턴스 변수로 이동하십시오. 그래서 클래스에 조롱 된 스텁을 설정하고 테스트 클래스에서 검증 및 주장을 할 수 있습니다. 예 :

@Test 
public void testSMth(){ 
    wsProvider.setStub(stubMock); 
    verify(stubMock).sendMsg(); 
    ...asserts 
} 

이 접근법은 스레드 안전성이 아니며 일부 동시성 수정을 수행해야합니다. 이 수정으로 인해 실수가 발생할 수 있습니다. 그래서 지역 변수 approce에는 스레드가 안전합니다.

또한 WebServiceStub의 인스턴스를 반환하는 팩토리를 만들 수 있습니다. 그러나이 상황은 빈번하기 때문에이 접근법은 새로운 수업을 만들어 낼 것입니다.

질문 :이 사례를 테스트하고 실수로 테스트 비용을 수정하는 방법은 무엇입니까?

+1

생성 된 WebService 클래스를 나타 내기 위해 'stub'을 사용하여 자신과 다른 모든 사람들을 혼란스럽게합니다. 이것은 빈번한 사용법이지만 단위 테스트 환경에서 '스텁'은 완전히 다른 것을 의미합니다. – artbristol

답변

4

클래스에는 필드로 WebService 개체 ('스텁'이라고하기를 거부 함)가 있어야합니다.

class Someclass{ 

    @Resource 
    private WebService ws; 

    public void sendMessage(){ 

    ws.sendMsg();   
    } 
} 

DI 프레임 워크를 주입해야합니다. 테스트에서는 모의로 설정할 수 있습니다. 게으른 getter가 필요하지 않습니다. thread-safe는 아닙니다.

+0

필자의 DI 프레임 워크 (ATG Dynamo) 클래스에는 setter와 getter가 있어야합니다. – Oleksandr

+0

출력기를 사용하지 않고 테스트시 변수를 설정할 수 없습니다. – Oleksandr

+0

다음에 세터를 넣으십시오 :-) – artbristol

0

스텁 == Null 인 경우 스텁을 거의 인스턴스화하지 않습니다. 대신 ArgumentNullException이 Throw됩니다. Null은 결코 유효한 인수로 받아 들여서는 안됩니다 (정말로, 정말 좋은 이유가 없다면).

+0

내가 분명하지 않다면 미안 해요. "진짜"사례에 대한 if() 문. 스텁은 테스트 클래스가 아닌 코드를 처리 할 때마다 null이됩니다.하지만 ws 스텁에 대한 조언을 주셔서 감사합니다. – Oleksandr

3

constructor injection을 사용하면 종속성이 설정되지 않을 가능성을 피할 수 있습니다. 이렇게하면 테스트에서 가짜를 쉽게 사용할 수 있습니다.

WebServiceStub 클래스가 사실 인 경우 - 스레드로부터 안전하지 않습니다 (그러나 WebServiceStub는 JAX-WS에 의해 생성되는 경우, 당신은 지하철/JAX-WS 스텁은 종종 스레드 안전하다는 것을 알아야한다), 다음 네, 당신은해야합니다 공장을 이용하십시오. 이것은별로 큰 문제가 아니며 그렇게 느리게해서는 안됩니다. 원하는 경우 정적 내부 클래스를 사용할 수 있습니다.

관련 문제