2011-07-28 3 views
5

나는 I1에서 다음과 같이 구현 ILogger에 어댑터가 :복잡하지 않은 코드없이 어댑터 용 JUnit을 작성하는 방법은 무엇입니까?

class BAdapter() implements I1 
{ 
    void logA() { // nothing } 
    void logB() { new BLogger().log() } 
    void logC() { // nothing } 
} 
내가 JUnit 테스트를 작성하려합니다

, 그 기능을 확인,하지만 난 내 모의 개체를 대신 주입 할 수 없기 때문에 나는 그것이 조금 문제가 발견 BLogger이거나 반환 값을 확인하십시오. 몇 가지 가능한 해결책을 찾았지만 확실하지 않습니다. 어느 것이 가장 좋습니다.

사례 하나 :BAdapter 클래스에 void setLogger(Logger l)를 추가합니다.

class BAdapter() implements I1 
{ 
    private Logger logger = new BLogger(); 

    public void logB() { logger.log() } 
    public void setLogger(Logger l) { logger = l } 
    .. //rest of methods 
} 

단점 : "실제"테스트 코드가 아닌 세터를 추가하는 이유는 무엇입니까?

사례 2 : 보호 팩토리 방법을 추가하고 테스트 패키지에 BAdapter을 서브 클래스로 추가하십시오.

단점 : 이것이 깨끗하고 세련된 해결책 인 경우 확실하지 않지만 여기에는 별다른 단점이 없습니다.

사례 3 : 초록 팩토리 패턴을 사용하십시오. 테스트에서

class BAdapter() implements I1 
{ 
    public void logB() { AbstractFactory.getFactory().getBLogger().log() } 
    .. //rest of methods 
} 

그리고 어딘가에 :

AbstractFactory.setFactory(new MockLoggersFactory()) 

단점 : 이것은 너무 복잡한가요?

사례 4 : 예를 들어 로깅이 수행 될 때 부울 반환. 예 :

class BAdapter() implements I1 
{ 
    Boolean logA() { return false; } 
    Boolean logB() { return new BLogger().log() } 
    Boolean logC() { return false; } 
} 

단점 : 이것은 일종의 wourkaround입니다. "실제"비 테스트 코드에서 아무도 필요하지 않을 때 어떤 가치를 반환해야하는 이유는 무엇입니까?

더 나은 솔루션? 더 좋은게 있나요?

답변

2

코드에서 테스트중인 클래스가 달성하고자하는 것이 무엇인지 정확히 알기는 어렵지만 사례 코드와 함께 '실제 코드'에 주입을 사용한다는 경고가 함께 표시됩니다.

주입의 장점 중 하나는이 경우 어댑터를 더 재사용 할 수있게 만드는 것입니다. logB 메서드가 항상 BLogger 인스턴스에 위임하도록 강제하면 컴파일 타임에 해당 동작이 돌로 설정됩니다. 어댑터를 다른 유형의 Logger으로 위임하려면 해당 어댑터를 사용할 수 없으므로 재사용 가능성이 약간 떨어집니다.

+0

JUnit in Action 서적에서 비슷한 접근법을 발견했습니다. 테스트 코드는 다른 코드와 마찬가지로 코드의 클라이언트이므로 Unit 테스트 요구 사항에 맞게 코드를 다시 팩터링하거나 업데이트하는 것이 좋습니다. –

0

특히 테스트에서 사용되는 IMVHO 코드는 사용하지 않아도되는 기능을 노출 할 수 있기 때문에 좋은 생각이 아니지만 일부는 사용하기에 시원하고 놀람을 당할 수도 있습니다.

이렇게하면 일반적으로 매우 좋은 접근 방법 인 경우 3을 남겨 둡니다. 그러나 테스트 중에 만 과도한 잔인 함이 사용되는 경우에도 마찬가지입니다.

내가 편리한 방법으로 클래스에서 private 필드를 변경할 수 있습니다 PowerMock 같은 몇 가지 추가 조롱 프레임 워크를 사용하는 것이 좋습니다 것

:

Whitebox.setInternalState(loggerInstance, "logger", new MockLogger()); 
을 : 일부 모의에 스왑에게 필드 테스트를하는 동안 다음

class BAdapter() implements I1 
{ 
    private Logger logger = new BLogger(); 

    public void logB() { logger.log() } 
    .. //rest of methods 
} 

자세한 정보 : http://code.google.com/p/powermock/wiki/BypassEncapsulation

조롱 프레임 워크는 테스트 중 큰 자산이므로 도움이된다는 것을 알고 있습니다. 많이.

관련 문제