2010-01-30 4 views
17

테스트를 성공적으로 통과 한 독립형 싱글 톤을 사용하고 있습니다. 그러나 일단 테스트가 수행되면 싱글 톤이 정의되면 인스턴스를 재설정 할 수 없으므로 실패합니다.JUnit 테스트를 사용하는 다른 싱글 톤 인스턴스

이 문제를 해결하는 방법에 대한 아이디어가 있으십니까?

답변

9

싱글 톤을 사용하지 마십시오.

특히 싱글 톤과 전역 변수의 유일한 차이점은 싱글 톤이 단일 인스턴스를 적용하려고한다는 것입니다 (예 : 생성자를 비공개로 설정).

대신 생성자를 public으로 만들고 새 인스턴스를 사용하여 테스트를 작성하십시오. 실제 프로그램에서 getInstance()을 사용하여 표준 전역 인스턴스를 가져 오거나 IOC 컨테이너를 사용하십시오.

그리고 기억하십시오 singletons are pathological liars.

여전히 Singleton에 익숙하지 않은 경우 생성자를 public으로 만드는 대신 public (정적) 팩토리 메서드를 추가하여 실수로 사용할 수없는 방식으로 인스턴스를 만들 수 있습니다. 예 :

public static MyClass TEST_CreateInstance() { 
    return new MyClass(); 
} 
3

싱글 톤을 제거하는 메서드를 추가 할 수 있습니다 (예 : destroyMe(); 모든 것을 초기화 해제하고 싱글 톤의 인스턴스를 null로 설정합니다.

public void destroyMe(){ 
    this.instance = null; 
    //-- other stuff to turn it off. 
} 
그래도 동기화 문제를 떠나

)

그런데 왜 당신은 각 시험에 대한 귀하의 싱글을 다시 초기화해야합니까? 싱글 톤의 개념에 따라 다를 수 없습니다.

10

사용자가 초기화 된 인스턴스를 저장하기 위해 싱글 톤 클래스 내에 개인 정적 필드가 있다고 가정합니다.

코드를 수정하지 않으려는 경우 모든 테스트가 끝날 때마다 실행되는 teardown 메서드를 정의 할 수 있습니다.이 메서드에서는 here과 같이 리플렉션을 통해이 정적 필드를 null로 설정할 수 있습니다.

+1

-1, IMO이 상황이 악화되고 있습니다. – orip

+13

+1 실제 솔루션을 제공합니다. 나는 싱글 톤 코드 인 제 3 자 코드를 통제 할 수 없으며 해결책을 필요로한다. 어떻게해야하는지에 대해서는 조언하지 않았다. – eis

1

은 일반적으로 싱글 톤에주의해야하며, 악의적 인 디자인, 나쁜 디자인 및 유지 관리에 좋지 않은 큰 글로벌 변수를 나타내는 경향이 있습니다.

은 아직도 그 자리에 테스트 먼저 당신이 할 수 얻을 수 있습니다 :

 

static setInstance(...){ //package visibility or in difficult cases you have to use public 
    instance = ...; 
} 
 

이 해결 더 말했듯이. 그래서 첫 번째 테스트 장소를 얻을 수 있지만 리팩토링자를 싱글 톤 패턴에서 멀리 떨어지십시오.

0

싱글 톤 인스턴스는 테스트 자체에서 SUT로 전달되어야합니다. 즉, 각 테스트마다 싱글 톤 (및 소멸)을 생성합니다. Mockito와 같은 IoC 및 조롱 프레임 워크를 채택하면이 접근법을 거의 사소한 것으로 만듭니다.

1

나는 매우는 디자인 패턴으로 멀리 싱글 톤에서 이동 및 범위 (의존성 주입)으로 싱글 톤을 사용하는 것이 좋습니다. 이렇게하면 문제가 사라집니다.

그러나 싱글 톤의 세계에 빠져 있다고 가정하면 싱글 톤 또는 종속성을 테스트하는지에 따라 몇 가지 옵션이 있습니다.

종속 항목을 테스트하는 경우 PowerMockJMockIt을 사용하여 싱글 톤을 조롱 할 수 있습니다. 이 문제를 해결하는 방법에 대한 지침은 Runtime.getRuntime을 조롱하는 것에 대한 내 previous post을 참조하십시오.

싱글 톤을 테스트하는 경우 구성 규칙을 완화하거나 싱글 톤에 "재설정"방법을 제공해야합니다.

1

스프링은 각 테스트 케이스에 대한 싱글 톤 빈의 새로운 인스턴스가 필요한 특별한 사용 사례에 대해 DirtiesContext 주석을 제공합니다. 이것은 기본적으로이 주석이 적용된 각 테스트 케이스/테스트 클래스에 대한 새로운 어플리케이션 컨텍스트를 생성합니다.