Programing

PowerMock을 사용하여 테스트를위한 비공개 방법을 모의하는 방법은 무엇입니까?

lottogame 2020. 12. 8. 07:38
반응형

PowerMock을 사용하여 테스트를위한 비공개 방법을 모의하는 방법은 무엇입니까?


비공개 메소드를 호출하는 공개 메소드로 테스트하고 싶은 클래스가 있습니다. 개인 방법이 올바르게 작동한다고 가정하고 싶습니다. 예를 들어, doReturn....when.... PowerMock을 사용하여 가능한 솔루션 이 있음을 발견 했지만이 솔루션은 저에게 적합하지 않습니다. 어떻게 할 수 있습니까? 누구든지이 문제가 있었습니까?


여기서 문제가 보이지 않습니다. Mockito API를 사용하는 다음 코드로 그렇게 할 수있었습니다.

public class CodeWithPrivateMethod {

    public void meaningfulPublicApi() {
        if (doTheGamble("Whatever", 1 << 3)) {
            throw new RuntimeException("boom");
        }
    }

    private boolean doTheGamble(String whatever, int binary) {
        Random random = new Random(System.nanoTime());
        boolean gamble = random.nextBoolean();
        return gamble;
    }
}

다음은 JUnit 테스트입니다.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;

@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {

    @Test(expected = RuntimeException.class)
    public void when_gambling_is_true_then_always_explode() throws Exception {
        CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());

        when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class))
                .withArguments(anyString(), anyInt())
                .thenReturn(true);

        spy.meaningfulPublicApi();
    }
}

(모든 테스트 프레임 워크와 함께 작동합니다 일반적인 솔루션 경우 클래스가 비이다가 final) 수동으로 자신의 모형을 만드는 것입니다.

  1. 개인 방법을 protected로 변경하십시오.
  2. 테스트 클래스에서 클래스를 확장하십시오.
  3. 원하는 상수를 반환하려면 이전 개인 메서드를 재정의하십시오.

이것은 프레임 워크를 사용하지 않으므로 우아하지는 않지만 PowerMock이 없어도 항상 작동합니다. 또는 1 단계를 이미 완료 한 경우 Mockito를 사용하여 2 단계와 3 단계를 수행 할 수 있습니다.

개인 메서드를 직접 모의하려면 다른 답변에 표시된대로 PowerMock을 사용해야 합니다.


나는 당신이 mockito에서 테스트하기 위해 개인 함수라고 부를 수있는 방법을 알고 있습니다.

@Test
    public  void  commandEndHandlerTest() throws  Exception
    {
        Method retryClientDetail_privateMethod =yourclass.class.getDeclaredMethod("Your_function_name",null);
        retryClientDetail_privateMethod.setAccessible(true);
        retryClientDetail_privateMethod.invoke(yourclass.class, null);
    }

어떤 이유로 Brice의 대답이 저에게 효과가 없습니다. 나는 그것을 작동시키기 위해 약간 조작 할 수 있었다. PowerMock의 최신 버전이 있기 때문일 수 있습니다. 1.6.5를 사용하고 있습니다.

import java.util.Random;

public class CodeWithPrivateMethod {

    public void meaningfulPublicApi() {
        if (doTheGamble("Whatever", 1 << 3)) {
            throw new RuntimeException("boom");
        }
    }

    private boolean doTheGamble(String whatever, int binary) {
        Random random = new Random(System.nanoTime());
        boolean gamble = random.nextBoolean();
        return gamble;
    }
}

테스트 클래스는 다음과 같습니다.

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

import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.doReturn;

@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {
    private CodeWithPrivateMethod classToTest;

    @Test(expected = RuntimeException.class)
    public void when_gambling_is_true_then_always_explode() throws Exception {
        classToTest = PowerMockito.spy(classToTest);

        doReturn(true).when(classToTest, "doTheGamble", anyString(), anyInt());

        classToTest.meaningfulPublicApi();
    }
}

인수없이 :

ourObject = PowerMockito.spy(new OurClass());
when(ourObject , "ourPrivateMethodName").thenReturn("mocked result");

String인수 :

ourObject = PowerMockito.spy(new OurClass());
when(ourObject, method(OurClass.class, "ourPrivateMethodName", String.class))
                .withArguments(anyString()).thenReturn("mocked result");

참고URL : https://stackoverflow.com/questions/7803944/how-to-mock-private-method-for-testing-using-powermock

반응형