<!--powermock-->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
测试类中加入注解:
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*","javax.script.ScriptEngineFactory"}) //Resolve prompted classloader error
一、如果单纯的测试某一个类中的某个方法,该方法内没有调用外部类的方法(本类除外),可单纯创建实例和引入要模拟的对象
@InjectMocks
private XmlCustomizedDataFieldsServiceImpl service; //要测试的类
@Mock
private XmlCustomizedDataFieldsMapper xmlCustomizedDataFieldsMapper; //测试方法需要mock的对象
例子:
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*","javax.script.ScriptEngineFactory"})
@InjectMocks
private XmlCustomizedDataFieldsServiceImpl service;
@Mock
private XmlCustomizedDataFieldsMapper xmlCustomizedDataFieldsMapper;
@Mock
private XmlCustomizedDataFieldsDTO dto;
private static final int VALUE=123;
@Test
public void addXmlCustomizedDataFieldsDTO() {
when(xmlCustomizedDataFieldsMapper.insert(any(XmlCustomizedDataFieldsDTO.class))).thenReturn(VALUE);
int res = service.addXmlCustomizedDataFieldsDTO(dto);
Assert.assertEquals(VALUE, res);
}
}
重点讲第二种,当测试的方法中有调用其他外部类的方法时,用spy创建测试类实例,用Whitebox引入所调用外部方法所在的类
public class XmlCustomizedDataFieldsServiceTest {
@InjectMocks
private XmlCustomizedDataFieldsServiceImpl service;
@Mock
private ProfilesService profilesService; //此对象要和被测试类中引入的对象一模一样
@Mock
private XmlTemplateService xmlTemplateService;
public void testXXXX() {
XmlCustomizedDataFieldsServiceImpl re = spy(new XmlCustomizedDataFieldsServiceImpl());
Whitebox.setInternalState(re,"profilesService",profilesService);
Whitebox.setInternalState(re,"xmlTemplateService",xmlTemplateService);
}
测试public void方法:
@Test
public void getElementList()throws Exception{ //method of testing void & public
XmlCustomizedDataFieldsServiceImpl re = spy(new XmlCustomizedDataFieldsServiceImpl());
Document document = DocumentHelper.createDocument();
document.addElement(ELEMENT);
Element rootElement = document.getRootElement();
doNothing().when(re,"replaceValue",any(Element.class),anyList());//测试的方法调用了外部的方法,可以直接mock,不走真实的一步
re.getElementList(rootElement, getList());
verify(re, times(1)).getElementList(any(Element.class), anyList());
}
测试private void方法
@Test
public void replaceValue()throws Exception{ //method of testing void & private
XmlCustomizedDataFieldsServiceImpl re = spy(new XmlCustomizedDataFieldsServiceImpl());
Document document = DocumentHelper.createDocument();
document.addElement(ELEMENT);
Element rootElement = document.getRootElement();
doNothing().when(re, "replaceValue", any(Element.class), anyList());//模拟调用一次该方法不应返回任何东西
Whitebox.invokeMethod(re, "replaceValue", rootElement,getList());
verifyPrivate(re, times(1)).invoke("replaceValue", any(Element.class), anyList());
}
测试含引用外部类静态方法的方法:
@Test
public void specifyEnvironment() throws Exception{
XmlCustomizedDataFieldsServiceImpl re = spy(new XmlCustomizedDataFieldsServiceImpl());
Whitebox.setInternalState(re,"dictionaryService",dictionaryService);
mockStatic(GetCustomizationDataMapper.class);//测试方法内有调用外部类的静态方法时,先mock该类
doReturn("AUUIIA").when(dictionaryService).getCountryCodeFromTab(anyString());
doReturn(getMap()).when(GetCustomizationDataMapper.class,"beforeGetCustomizationData",any(ProfilesDTO.class),anyString(),anyString());//引用的外部类的静态方法
Map<String, Object> map = re.specifyEnvironment(getProfilesDTO(), COUNTRYCODE);
Assert.assertNotNull(map);
}
@PrepareForTest({GetCustomizationDataMapper.class}) //在测试类头加上
测试时候如果有用到静态,或者私有,final的方法时,必须在测试的类中上添加注解@PrepareForTest()
里面放入需要用到这种方法所在的类
如@PrepareForTest({AAA.class,BBB,class})