2013-03-28 7 views
0

필자는 항상 테스트 방법으로 오버라이드 한 클래스의 보호 된 메소드 getDate()를 사용하여 이러한 방식으로 날짜를 테스트했습니다. 예 :싱글 톤 테스트 날짜

public class MyClass { 
    protected Date getDate(){ 
     return new Date(); 
    }; 
} 

테스트 :

이 날에 충분했다
MyClass myclass = new MyClass(){ 
    @Override 
    protected Date getDate(){ 
     return new Date(1234567890); 
    } 
}; 

하지만, 다음과 같은 문제가 나타나 은 내가 한 번 인스턴스화 할 클래스를, 그래서 내가 싱글 톤 패턴을 사용 :

public static Something getInstance() { 
    if (instance == null) { 
     instance = new Something(); 
    } 

    return instance; 
} 

문제는이 방법으로 개체를 만들어야한다는 것입니다. Something.getInstance() - 개체가 그 메서드 내에 만들어졌습니다. getInstance 내에서 getDate 메서드를 재정의 할 수 없습니다. 왜냐하면 이해가 안되기 때문입니다 (때로는 실제 인스턴스가 필요하며 가끔씩 인스턴스가 필요하기도합니다). 이것은 내가 그런 상황에서 날짜를 테스트하는 방법에 대한 질문으로 이어진다.

+0

Powermock과 같은 최신 조롱 프레임 워크를 사용하십시오. 그것은 오늘가는 길입니다 ... – ppeterka

+0

실제로하고 싶은 일은 ...? – Ankit

+0

날짜 테스트의 목표는 무엇입니까? 날짜가 제대로 작성되었는지 확인하는 중이면 테스트 할 필요가 없으며 이미 테스트 된 것입니다. 이른바'test-all' 접근법을 사용하지 마십시오. 대신, 날짜가 어떻게 든 알고리즘/방법/문제에 중요하다면 조크 프레임 워크 (JMock, EasyMock, Mockito, Powermock 등)를 사용한다고 생각해야합니다. – ThanksForAllTheFish

답변

0

캡처를 사용해야하는 소리가 많이 들립니다 (EasyMock이 옵션이 될 수 있음).

0

여러분이 싱글 톤에 getDate() 메소드를 넣으면 global state으로 알려져 있습니다. 테스트 목적으로 모의하는 것은 거의 불가능합니다. 유일한 대안은 테스트 프레임 워크를 사용하거나 클래스를 "진정한"싱글 톤이 아니라 다른 인스턴스에서 인스턴스화 할 수 있도록 보장하는 것입니다. 나는 후자의 선택이 올바른 접근법이라고 주장 할 것이고이 경우에는 싱글 톤을 사용해서는 안된다.

1

평범한 자바 싱글 톤을 사용할 때마다 방금 눈치 챘을 때 테스트 할 수없는 코드를 만듭니다.

클래스의 인스턴스를 하나만 가질 수있는 다른 방법이 있습니다. 단순한 것부터 - 한 번만 생성하십시오 :) Spring과 같은 IoC 프레임 워크를 사용하여 관심을 갖도록합니다.

글로벌 상태에 대한 섹션 Misko Hevery's guide to writing testable code을 살펴 보시기 바랍니다.

+0

+1 링크 : 항상 흥미로운 읽기 ;-) 너무 늦기 전에 싱글 톤을 죽이라는 제안에 대해서. – assylias

1

하는 경우, 그리고 싱글 톤 패턴은 어떤 희생을 치르더라도 피할 수없는 경우에만 경우 , 당신은 Powermock를 사용하여 Something 클래스의 건설을 조롱 수 :

//create mock instance,  
Something mockSomethingInstance = createMock(Something.class); 
//create your Date instance to return 
Date d = new Date(); 
when(mockSomethingInstance.getDate()).thenReturn(d); 

을 당신은 뭔가 클래스의 생성자를 조롱해야 (항상 을주의해야합니다. 그러나이 작업을 수행하면 Something 클래스의 다른 모든 구성이 무효화됩니다.이 경우 싱글 톤이므로 정상적으로 처리됩니다.) :

당신이 너무 Something 클래스에서의 getInstance 기능을 조롱 수 있도록 또한 0
expectNew(Something.class).andReturn(mockSomethingInstance); 

, Powermock can mock static function calls too는, 그러나

//mock the static functions 
mockStatic(Something.class);   

expect(Something.getInstance()).andReturn(mockSomethingInstance); 
//have to replay the class in order to work 
replay(IdGenerator.class); 

당신은 클래스 자체의 동작을 테스트 할 때, 나는, 당신이 partial mocking을한다고 가정 . 그러나 이것은 더 추악하고 못 생기기 시작하고 있습니다. ...

모두 : 싱글 톤을 사용하기 전에 두 번 생각하십시오 - 단순한 것처럼 보이지만 (물론 onlz는 물론 ...), 장기적으로 볼 수 있습니다. 빠르게 악몽에 빠지게됩니다 ... 봄을 사용하는 것은 똑같은 일을하는 훨씬 더 깨끗한 방법이며, 많은 두통을 덜어줍니다.