powerMock Junit单元测试

<!--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})

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
junit4和powermock是两个常用的Java测试框架,它们常被开发人员用来进行单元测试junit4是一个成熟的单元测试框架,用于编写和运行Java程序的测试用例。它可以帮助开发人员在开发过程中及时发现代码中的错误,提升代码的质量。junit4提供了一系列的注解和断言来简化测试用例的编写,并且可以与各种开发工具和持续集成工具进行集成。 与此同时,powermock是一个用于扩展junit4的工具,可以帮助开发人员进行更加灵活和强大的单元测试。它可以模拟和修改Java程序中的一些难以测试的对象和行为,例如静态方法、私有方法和构造函数等。powermock使用了一种称为“字节码操作”的技术,能够改变Java字节码的执行路径,从而达到模拟和修改的目的。 使用junit4和powermock可以让开发人员编写更加全面和准确的单元测试用例。在测试过程中,我们可以使用junit4来编写测试用例的框架和断言,而使用powermock来模拟和修改需要被测试的对象。这样就可以在保持单元测试的独立性和可重复性的同时,更好地模拟和验证代码中的行为。 总的来说,junit4和powermock是两个非常有用的Java测试框架。它们可以一起使用,为开发人员提供更强大和灵活的单元测试能力。通过编写全面和准确的单元测试用例,可以提高代码的质量和可维护性,同时也可以减少程序中的BUG和错误。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值