2012-03-06 4 views
43

내 프로젝트에서 몇 가지 정적 util 메서드가 있는데, 그 중 일부는 그냥 통과하거나 예외를 throw합니다. void가 아닌 반환 유형을 가진 정적 메서드를 모의하는 방법에 대한 많은 예제가 있습니다. 하지만 공백을 반환하는 정적 메서드를 "doNothing()"으로 조롱하는 방법은 무엇입니까?PowerMock에서 void를 반환하는 정적 메서드를 조롱하려면 어떻게해야합니까?

비 무효 버전은 코드의이 라인을 사용

@PrepareForTest(StaticResource.class) 

...

PowerMockito.mockStatic(StaticResource.class); 

을 ... 반환하는 StaticResources에 적용하지만 경우

Mockito.when(StaticResource.getResource("string")).thenReturn("string"); 

void, 컴파일은 when(T)이 void에 해당하지 않는다고 불평 할 것입니다 ...

아이디어가 있으십니까?

해결 방법은 모든 정적 메서드가 성공하기 위해 일부 Boolean을 반환하는 것일 수 있지만 해결 방법을 싫어합니다.

답변

25

실제 인스턴스에서 Mockito를 사용하는 것과 같은 방법으로 할 수 있습니다. 예를 들어 당신이 체인 스텁, 다음 줄은 첫 번째 통화를 만들 수있는 예외가 발생합니다 다음 두 번째 아무것도 및 getResources 향후 전화를하지 않는다 :주의, 매트 Lachman의 발언에

// the stub of the static method 
doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

// the use of the mocked static code 
StaticResource.getResource("string"); // do nothing 
StaticResource.getResource("string"); // throw Exception 

감사를 그 기본 경우 모의 생성 시간에 응답이 변경되지 않으면 모의 기본값으로 아무것도 수행하지 않습니다. 따라서 다음 코드를 작성하는 것은 작성하지 않는 것과 같습니다.

doNothing().doThrow(Exception.class).when(StaticResource.class); 
StaticResource.getResource("string"); 

그렇지만이 특정 코드에 대해서는 아무 것도 기대치 않는다는 테스트를 읽는 동료에게 흥미로울 수 있습니다. 물론 이것은 어떻게인지에 따라 적응 될 수 있습니다 이해가 시험입니다.


는 그건 그렇고, 내 소견에 당신은 당신이 새로운 코드를 공예 경우 정적 코드를 조롱하지 않도록해야합니다. Mockito는 일반적으로 나쁜 디자인에 대한 힌트라고 생각합니다. 유지 관리가 어려운 코드로 이어질 수 있습니다. 기존 레거시 코드는 아직 또 다른 이야기입니다.

일반적으로 개인 또는 정적 메서드를 조롱해야하는 경우이 메서드는 너무 많은 작업을 수행하므로 테스트 된 개체에 삽입 할 개체에 외부화해야합니다.

희망이 있습니다.

감사

+1

불행히도 즉,()는 변수를 수용하고 정적 리소스는 타입 때와 작동하지 않을 것이다. ('StaticResource를 변수로 해석 할 수 없습니다') – Pete

+0

오, 죄송합니다. 내 코드가 틀렸으니 비 정적 모의 객체에 익숙해 져야합니다. 어쨌든 올바른 구문을 반영하도록 ansswer를 업데이트했습니다. – Brice

+0

감사! 따라서 종속성이없는 정적 도우미 메서드를 사용하는 것은 나쁜 생각입니까? 물론 작업을 수행하는 객체를 삽입하고 객체화 할 수는 있지만 정적 객체에 의존성이없는 작업자가 독립성을 나타낼 수있는 것처럼 느껴집니다. – Pete

55

할 수 있습니다 스텁과 같은 정적 무효 방법 : 당신이 귀찮게 왜 당신이 mockStatic (정적 리소스를 호출 할 때하기 때문에 나는 확실하지 않다 있지만

PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString()); 

.클래스) 정적 리소스에 모든 정적 방법은 기본

더 유용합니다, 당신은 StaticResource.getResource (에 전달 된 값)이 같은 캡처 할 수 있습니다 스텁에 의해 다음과 같습니다

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); 
PowerMockito.doNothing().when(
       StaticResource.class, "getResource", captor.capture()); 

는 그런 다음 문자열을 평가할 수를 그 이 같은 StaticResource.getResource에 전달 : 당신이 선 아래 모의을 원하는 경우

간단 측면에서
String resourceName = captor.getValue(); 
+0

이렇게 할 수 있다는 것은 시간의 다른 양/적은 시간/전혀 시간을 위해 잠을 자도록 Thread.sleep (long millis)를 조롱하는 것과 같은 것을 할 수 있기 때문에 매우 멋지다! – fragorl

+0

예제에서 "getResource"와 같이 메서드에 문자열을 사용하는 것을 피할 수있는 방법이 있습니까? –

8

, 상상 :

다음
StaticClass.method(); 

당신은 모의에 코드의 라인 아래 연락처 :

PowerMockito.mockStatic(StaticClass.class); 
PowerMockito.doNothing().when(StaticClass.class); 
StaticClass.method(); 
1

는, 예를 들어 대한 무효 반환 정적 메서드를 조롱하기 Fileutils.forceMKdir(File file),

샘플 코드 :

File file =PowerMockito.mock(File.class); 
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file); 
관련 문제