PowerMockito 의 기본 사용 분석

PowerMockito 는 Mockito 와 자주 결합 하여 사용 합 니 다.먼저 이 두 가지 소 개 를 하 겠 습 니 다.
1.Mockito 와 PowerMockito 의 소개
Mockito 와 PowerMockito 는 무엇 일 까요?그들 은 어떤 작용 을 합 니까?
Mocktio 와 PowerMockito 는 모두 Mock 의 도구 류 로 주로 자바 의 라 이브 러 리 이 고 Mock 은 위장 이라는 뜻 이다.
그들 은 단원 테스트 에 적용 된다.단원 테스트 에 있어 서 우 리 는 제3자 의 구성 요소,예 를 들 어 데이터 베이스,Webservice 등 에 의존 하고 싶 지 않다.단원 테스트 를 작성 할 때 우 리 는 제3자 에 게 의존 해 야 하 는 상황 을 만나면 Mock 의 기술 을 사용 하여 우리 가 원 하 는 결 과 를 위조 할 수 있다.
자바 에 있어 서 mock 의 대상 은 주로 자바 방법 과 자바 류 이다.
다음은 Mockito 와 PowerMockito 를 어떻게 사용 하여 Mock 을 진행 하 는 지 소개 하 겠 습 니 다.
2.Mockito 와 PowerMockito 의 차이
내 가 보기에 PowerMockito 는 Mockito 의 증강 이다.그들의 PowerMockito 는 Mockito 를 호출 하 는 방법 이지 만 Mocktio 가 Mockito 를 사용 할 수 없 는 대상 이나 방법 에 대해 우 리 는 PowerMockito 를 사용 하여 실현 할 수 있다.
예 를 들 어 Mockito 는 static Method,final method,매 거 진 클래스,private method 에 사용 할 수 없습니다.이런 것들 은 PowerMockito 로 실현 할 수 있 습 니 다.PowerMockito 와 mockito 가 결합 하여 사용 할 때 우 리 는 호환성 문 제 를 고려 해 야 합 니 다.
양자 의 판본 은 호 환 이 필요 하 다
Mockito
PowerMockito
2.8.9+
2.x
2.8.0-2.8.9
1.7.x
2.7.5
1.7.0RC4
2.4.0
1.7.0RC2
2.0.0-beta - 2.0.42-beta
1.6.5-1.7.0RC
1.10.8 - 1.10.x
1.6.2 - 2.0
1.9.5-rc1 - 1.9.5
1.5.0 - 1.5.6
1.9.0-rc1 & 1.9.0
1.4.10 - 1.4.12
1.8.5
1.3.9 - 1.4.9
1.8.4
1.3.7 & 1.3.8
1.8.3
1.3.6
1.8.1 & 1.8.2
1.3.5
1.8
1.3
1.7
1.2.5
Ref: https://github.com/powermock/powermock/wiki/Mockito
3.구체 적 인 용법
본 고 는 구조 가 필요 한 인터페이스 와 반환 값 이 필요 한 인 터 페 이 스 를 실현 한다.
도입 의존

<dependencies>
	<dependency>
		<groupId>org.projectlombok</groupId>
		<artifactId>lombok</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context-support</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-test</artifactId>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.12</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.mockito</groupId>
		<artifactId>mockito-all</artifactId>
		<version>2.0.2-beta</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.powermock</groupId>
		<artifactId>powermock-module-junit4</artifactId>
		<version>1.7.4</version>
		<scope>test</scope>
	</dependency>
	<dependency>
		<groupId>org.powermock</groupId>
		<artifactId>powermock-api-mockito</artifactId>
		<version>1.7.4</version>
		<scope>test</scope>
	</dependency>
</dependencies>
Mock 이 필요 한 클래스:
ProcessDB.java

package com.github.mock.simple.vo; 
public class ProcessDB {    
    public ProcessDB(String ss){
        System.out.println(ss + " Enter ProcessDB ...");
    }
    
    public ProcessDB(){
        System.out.println("Enter ProcessDB ...");
    }
    
    public void getResultOfConnectDBNoReturn(String ss) {
        System.out.println(ss + " Enter getResultOfConnectDBNoReturn ...");
    }
    
    public String getResultOfConnectDB() {
        return "haha, Really went to the database";
    }
}
 
테스트 가 필요 한 클래스:
IUserService.java

package com.github.mock.simple.user; 
public interface IUserService { 
    public String testedMehtod(); 
}
UserServiceImpl.java

package com.github.mock.simple.user.impl; 
import org.springframework.stereotype.Service; 
import com.github.mock.simple.user.IUserService;
import com.github.mock.simple.vo.ProcessDB;
 
@Service
public class UserServiceImpl implements IUserService {
 
    @Override
    public String testedMehtod(){
        System.out.println("Enter UserServiceImpl testedMehtod ...");
        ProcessDB processDB = new ProcessDB("BB");
        processDB.getResultOfConnectDBNoReturn("AA");
        return processDB.getResultOfConnectDB();
    } 
}
BussinessService.java

package com.github.mock.simple.user.impl; 
import com.github.mock.simple.vo.ProcessDB; 
public class BussinessService {
    public String testedMehtod() {
        System.out.println("Enter BussinessService testedMehtod ...");
        ProcessDB processDB = new ProcessDB("BB");
        processDB.getResultOfConnectDBNoReturn("AA");
        return processDB.getResultOfConnectDB();
    }
}
테스트 클래스:
MockSpringSimpleTest.java

package com.github.mock.simple.test; 
import java.text.MessageFormat; 
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 
import com.github.mock.simple.user.IUserService;
import com.github.mock.simple.user.impl.BussinessService;
import com.github.mock.simple.user.impl.UserServiceImpl;
import com.github.mock.simple.vo.ProcessDB;
 
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(SpringJUnit4ClassRunner.class)//Spring   
@PrepareForTest({BussinessService.class,UserServiceImpl.class})
@ContextConfiguration(locations = {"classpath:applicationContext-mock-inject.xml"})
public class MockSpringSimpleTest {
 
    //  Spring   
    @Autowired
    IUserService userService;
 
    @Mock
    ProcessDB processDB;
    
    //   Spring    ,     
    @InjectMocks
    private BussinessService bussinessService;
 
    @Before
    public void initMocks() throws Exception {
        MockitoAnnotations.initMocks(this);
        //ReflectionTestUtils.setField(userService, "processDB", processDB);
        PowerMockito.whenNew(ProcessDB.class).withArguments("BB").thenReturn(processDB);
        // PowerMockito.whenNew(ProcessDB.class).withNoArguments().thenReturn(processDB);
    }
 
    @Test
    public void mockConnectDB() {
        String aa = "haha, everything is fake"; 
        PowerMockito.when(processDB.getResultOfConnectDB()).thenReturn(aa);
        PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA");
        System.out.println(bussinessService.testedMehtod());
        Assert.assertEquals("haha, everything is fake", bussinessService.testedMehtod());
    }
 
    @Test
    public void mockConnectDB2() {
        try {
            String aa = "haha, everything is fake";
            PowerMockito.when(processDB.getResultOfConnectDB()).thenReturn(aa);
            PowerMockito.doNothing().when(processDB).getResultOfConnectDBNoReturn("AA");
            System.out.println(userService.testedMehtod());
            Assert.assertEquals("haha, everything is fake", userService.testedMehtod());
        } catch (Exception ex) {
            System.out.println("--- getMessage ---");
            System.out.println(ex.getMessage());
            System.out.println();
            
            System.out.println("--- toString ---");
            System.out.println(ex.toString());
            System.out.println();
            
//            System.out.println("--- printStackTrace ---");
//            StringWriter stringWriter = new StringWriter();
//            PrintWriter printWriter = new PrintWriter(stringWriter);
//            ex.printStackTrace(printWriter);
//            System.out.println(stringWriter.toString());
//            System.out.println();
            
            System.out.println("--- printStackTrace DIY ---");
            System.out.println(ex.getClass().getName() + ": " + ex.getMessage());
            StringBuilder sbException = new StringBuilder();
            for (StackTraceElement ele : ex.getStackTrace()) {
                sbException.append(MessageFormat.format("\tat {0}.{1}({2}:{3})
", ele.getClassName(), ele.getMethodName(), ele.getFileName(), ele.getLineNumber()));; } System.out.println(sbException); sbException = null; // stringWriter = null; // printWriter = null; } } }
스캐닝 주입 xml
마지막 applicationContext-mock-inject.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans.xsd  
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context.xsd"> 
    <context:component-scan base-package="com.github.mock.simple"/> 
</beans>
실현 클래스 가 없 지만 의존 하 는 인터페이스 에 대해 applicationContext-mock-inject.xml 에 다음 과 같은 내용 을 추가 합 니 다(본 고 는 필요 없습니다).

<bean name="iXxService" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.github.mock.simple.api.IXxService"/>
</bean>
테스트 클래스 에 다음 코드 를 추가 합 니 다:

@Mock
iXxService iXxService;
@Before 에 아래 코드 를 추가 합 니 다.

ReflectionTestUtils.setField(userService, "iXxService", iXxService);
테스트 결과


PowerMockito 의 사용 방법
IT 에 의존 하 는 구성 요소 가 제대로 통합 되 지 않 으 면 mock 지원 테스트 가 필요 합 니 다.power mockito 를 사용 할 수 있 습 니 다.
특히 주의:
한 대상 에 대해 powermockito 를 진행 할 때 prepare 방법 에서 mock 이라는 대상 을 통일 해 야 합 니 다.그리고 다른 방법 으로 when 을 각각 호출 합 니 다.그렇지 않 으 면 여러 방법 에서 mock 을 진행 하면 오류 가 발생 할 수 있 습 니 다.
예 를 들 어 하나의 Service 가 IT case 의 밑바닥 에 있 고 일반적인 mock 은 전혀 들 어가 지 않 지만 우 리 는 통합 테스트 를 위해 이 testcase 에 단독으로 구멍 을 내 서 mock 대상 을 주입 할 수 없다.power mockito 의 강력 한 mock 능력 은 여기 서 사용 할 수 있 습 니 다.
예 를 들 면:
나의 mock 대상 impalaService 는 schmaMessagehandler 류 에서 new 로 나 왔 으 니 주 해 를 더 해 야 합 니 다.
먼저 test 류 의 시작 부분 에 머리 를 주석 하고 머리 류 는 mock 대상 이 있 는 클래스 입 니 다.

@RunWith(PowerMockRunner.class)
@PrepareForTest({HttpClient.class,SchemaMessageHandler.class})
다음:

PooledImpalaService impalaService = PowerMockito.mock(PooledImpalaService.class);
PowerMockito.whenNew(PooledImpalaService.class).withArguments((ConfigurationanyObject()).thenReturn(impalaService);
doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());
powermockito 를 사용 합 니 다.any()인 자 를 사용 할 때 예 를 들 어

doNothing().when(impalaService).createTable(anyString(),(Schema) anyObject());
매개 변수 목록 에서 any(),any***를 사용 하면 모든 매개 변 수 는 any 와 관련 된 매개 변 수 를 사용 해 야 합 니 다.그렇지 않 으 면 mock 이 성공 하지 못 합 니 다.
전체적으로 말 하면 it 에서 당신 만 mock 대상 을 원 합 니 다.예 를 들 어 A 류 에서 B 류 를 사 용 했 으 면 prepareForTest 에서 A 류 의 주 해 를 추가 할 수 있 습 니 다.
다음 과 같다.
@Prepare ForTest({A.class})그리고 it 에 B 클래스,B b=PowerMockito.mock(B.class)를 설명 합 니 다.이 럴 때 b 방법의 반환 값 이나 PowerMockit.do Nothing().when(b).방법 명()을 지정 하여 아무것도 하지 않도록 할 수 있 습 니 다.
마지막 으로 A 실례 화 를 말씀 드 리 겠 습 니 다.PowerMockit 는 mock 설정 순 서 를 중시 합 니 다.반드시 주의해 야 한다.
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기