PowerMockito는 단일 정적 메서드를 모의하고 객체를 반환합니다.


98

2 개의 정적 메서드, m1 및 m2를 포함하는 클래스에서 정적 메서드 m1을 모의하고 싶습니다. 그리고 m1 메서드가 객체를 반환하기를 원합니다.

나는 다음을 시도했다

1)

PowerMockito.mockStatic(Static.class, new Answer<Long>() {
         @Override
         public Long answer(InvocationOnMock invocation) throws Throwable {
            return 1000l;
         }
      });

이것은 반환 유형이 다른 m1과 m2를 모두 호출하므로 반환 유형 불일치 오류가 발생합니다.

2) PowerMockito.when(Static.m1(param1, param2)).thenReturn(1000l); 그러나 이것은 m1이 실행될 때 호출되지 않습니다.

3) http://code.google.com/p/powermock/wiki/MockitoUsagePowerMockito.mockPartial(Static.class, "m1"); 에서 얻은 mockPartial을 사용할 수 없다는 컴파일러 오류를 제공합니다 .

답변:


136

당신이 원하는 것은 1의 일부와 2의 모두의 조합입니다.

클래스의 모든 정적 메서드에 대해 정적 모의 를 활성화 하려면 PowerMockito.mockStatic을 사용해야합니다 . 이는 when-thenReturn 구문을 사용하여 스텁 이 가능하다는 것을 의미 합니다.

그러나 사용중인 mockStatic의 2 개 인수 오버로드는 모의 인스턴스에서 명시 적으로 스텁하지 않은 메서드를 호출 할 때 Mockito / PowerMock이 수행해야하는 작업에 대한 기본 전략을 제공합니다.

로부터 의 javadoc :

상호 작용에 대한 답변에 대해 지정된 전략을 사용하여 클래스 모의를 만듭니다. 상당히 고급 기능이며 일반적으로 괜찮은 테스트를 작성하는 데 필요하지 않습니다. 그러나 레거시 시스템으로 작업 할 때 유용 할 수 있습니다. 기본 응답이므로 메서드 호출을 스텁하지 않을 때만 사용됩니다.

기본 기본 스터 빙 전략은 개체, 번호 단지는 null, 0 또는 false로하고 평가 방법을 부울입니다. 2-arg 오버로드를 사용하면 "아니오, 아니요, 아니요, 기본적으로이 Answer 하위 클래스의 응답 메서드를 사용하여 기본값을 가져옵니다. Long을 반환하므로 호환되지 않는 항목을 반환하는 정적 메서드가있는 경우 오랫동안 문제가 있습니다.

대신 mockStatic의 1-arg 버전을 사용하여 정적 메서드의 스터 빙을 활성화 한 다음 when-thenReturn을 사용하여 특정 메서드에 대해 수행 할 작업을 지정합니다. 예를 들면 :

import static org.mockito.Mockito.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

class ClassWithStatics {
  public static String getString() {
    return "String";
  }

  public static int getInt() {
    return 1;
  }
}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStatics.class)
public class StubJustOneStatic {
  @Test
  public void test() {
    PowerMockito.mockStatic(ClassWithStatics.class);

    when(ClassWithStatics.getString()).thenReturn("Hello!");

    System.out.println("String: " + ClassWithStatics.getString());
    System.out.println("Int: " + ClassWithStatics.getInt());
  }
}

문자열 값 정적 메서드는 "Hello!"를 반환하도록 스텁 처리되고, int 값 정적 메서드는 기본 스텁을 사용하여 0을 반환합니다.


1
재생이 필요하지 않습니까?
Balaji Boggaram Ramanarayan 2014

흠 .. 그런 것 같아요. PowerMockito가 PowerMock을 재생 해줄까요? 그것도 궁금합니다.
djangofan 2015-10-26

3
하지만 일부 정적 메서드가 정확한 인수로 호출되는지 확인하려면 어떻게해야합니까?
elTomato

6
@PrepareForTest주석은 클래스해야 호출하는 정적 메소드가 아닌 정적 메소드가있는 클래스를.
Hazel Troost 2017

5
@HazelTroost-아니요, OP가 맞습니다. 테스트를 위해 준비해야하는 정적 메서드를 포함하는 클래스입니다. 그래서 @PrepareForTest(ClassWithStatics.class)맞습니다.
arry36
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.