iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >如何使用Mockito调用静态方法和void方法
  • 262
分享到

如何使用Mockito调用静态方法和void方法

2024-04-02 19:04:59 262人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

一、mock 静态方法 mockito库并不能mock静态方法,需要依赖powermock 第一步:给类添加注解 // 静态类优先加载,所以需要提前告诉powermock哪些静态

一、mock 静态方法

mockito库并不能mock静态方法,需要依赖powermock

第一步:给类添加注解


// 静态类优先加载,所以需要提前告诉powermock哪些静态类需要mock
@ContextConfiguration
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(springJUnit4ClassRunner.class)
@PrepareForTest(静态调用类.class)
public class SupplierServiceImplTest extends PowerMockTestCase {}

第二步:mock使用


@Test(expectedExceptions = BusinessException.class)
public void testAddSupplierAccount_genIdentityNoError() {
    // 告诉powermock,需要mock该类的所有静态方法
 PowerMockito.mockStatic(PassWordGenerator.class);
 
 final SupplierAccountDto supplierAccountDto = new SupplierAccountDto();
 supplierAccountDto.setName("小明");
 final String randomPWd = "666"; 
 PowerMockito.when(supplierDao.selectByEmail(anyString()))
   .thenReturn(new ArrayList<HaitaoSupplier>());
 // 静态方法mock
 PowerMockito.when(PasswordGenerator.genPwd()).thenReturn(randomPWd);
 PowerMockito.when(pwEncoder.encode(anyString())).thenReturn(randomPWd);
 PowerMockito.when(identityNoGenerator.genIdentityNo()).thenReturn(-1L);
 
 supplierServiceImpl.addSupplierAccount(supplierAccountDto); 
 verify(pwEncoder).encode(randomPWd);
}

二、mock void 方法


// void嘛,doNothing顾名思义
PowerMockito.doNothing().when(casService).addSupplier(anyLong(), any(ServiceKey.class));

使用PowerMockito和Mockito进行模拟测试

包括静态方法测试,私有方法测试等,以及方法执行的坑或者模拟不成功解决

一 普通spring项目

依赖:这个很重要,不同版本用法也有点区别:


<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-api-mockito</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.0</version>
    <scope>test</scope>
</dependency>
 
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-core</artifactId>
    <version>1.7.4</version>
    <scope>test</scope>
</dependency>

接下来就是mock测试了,使用完全模拟测试过程,对于需要测试接口中调用的静态,私有方法等,返回自己想要的预期结果,达到测试效果:

这里有几个要点:

测试过程中完全手动mock,不会真实调用或者产生数据

一 mock对象


order = mock(Order.class);
user = mock(User.class);

二 属性注入

将service等类中需要的其他service或者mapper等mock出来,然后分别使用工具类注入,名称保持一致即可


roomTypeService = mock(RoomTypeServiceImpl.class);
ticketComponetService = mock(TicketComponetServiceImpl.class);
hotelMapper = mock(HotelMapper.class);
//注入属性
ReflectionTestUtils.setField(orderService, "hotelGroupMapper", hotelGroupMapper);
ReflectionTestUtils.setField(orderService, "dsUtils", dsUtils);
ReflectionTestUtils.setField(orderService, "orderMapper", orderMapper);

三 静态方法mock

模拟静态方法返回结果需要使用PowerMockit,测试类上必须加注解@PrepareForTest


//account 获取stub
PowerMockito.mockStatic(Account.class);
Mockito.when(Account.get(anyString(), anyString(), anyString(), anyInt())).thenReturn(account);

四 私有方法

私有方法首先需要在类上加入注解,对于要测试的类中的public方法同样有效,比如测试方法中包含一个public方法,可以同样模拟:


@PrepareForTest(ConsumptionServiceImpl.class)  //里面写需要模拟私有方法的类class

然后对象不能mock,必须new一个,并且需要用spy处理:


orderService = PowerMockito.spy(new OrderServiceImpl());

接着使用doreturn .when这种形式模式,不能使用先when后return这种,会报错

注意一点,模拟参数要么全部模拟,要么全部自定义,不能混搭

这里有个大坑,如果出现私有方法还是进去执行的情况,很大可能是参数不对,比如你mock的参数是 anyString(),那么你真是测试时候传递的必须是一个String实例,不能是null,否则mock就会失败,我这里之前一直是对象的一个属性,直接new了一个对象传递

所以一直不成功:

比如 方法需要的是user.getId() ,而且你mock的是一个anyInt(),那么真正传递的时候必须给这个user,setId(9527),否则就无法达成预期的模拟效果,所有方法都一样!!


try {<br>        // 方法名,方法参数,必须全部对应,否则报错方法找不到
     PowerMockito.doReturn(1).when(orderService, "dateListMinBook",anyString(),anyString(),any(RoomType.class),anyString(),anyString());
     PowerMockito.doReturn(ResponseMessage.success().pushData("dateRoomTypeList",new ArrayList<DateRoomType>())).when(orderService, "eachDateNumAndPrice",any(Order.class),any(RoomType.class),anyBoolean(),anyInt(),anyString(),any(User.class));
     PowerMockito.doReturn("2000").when(orderService, "geTKEeptimeByWxcidAndHotelidAndLevel",anyString(),anyString(),anyString());
     PowerMockito.doNothing().when(orderService, "getPayWay",any(),any(),any(),any(),any());
 } catch (Exception e) {
     e.printStackTrace();
 }

五 预期结果

verify :判断方法执行了几次: 确定测试是否通过

例如:verify(userService, times(1)).queryUser(any(anyInt(),anyString(),anyString());

SpringBoot项目使用

1 依赖


<!-- S-junit -->
        <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-api-mockito2</artifactId>
            <version>2.0.0-beta.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>2.0.0-beta.5</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-core</artifactId>
            <version>2.0.0-RC.4</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.9</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>2.15.0</version>
        </dependency>
        <dependency>
            <groupId>org.assertj</groupId>
            <artifactId>assertj-core</artifactId>
            <version>3.12.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.easymock</groupId>
            <artifactId>easymock</artifactId>
            <version>4.0.2</version>
            <scope>test</scope>
        </dependency>
        <!-- E-junit -->

2 创建测试基类



@PowerMockRunnerDelegate(SpringRunner.class)
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "javax.security.*"}) //忽略一些mock异常
@SpringBootTest
public class TestBase {
}

3 创建特定的测试类


public class HotelControllerTest extends TestBase { //继承基类即可
    @Mock
    private HotelService hotelService;
    private Integer id;
//  加载sprinGContext进行mock测试,真实调用方法,不需要mock步骤
//     @Autowired
//     private HotelController hotelController;
//    纯mock测试,不加载springContext,执行mock操作,必须mock步骤,不会真实调用
    @InjectMocks
    private HotelController hotelController=new HotelController();
    // 应用到所有门店测试
    @Test
    public void detailTest(){
        System.out.println("test start.....");
        // 1 构造参数
        ininParams(1);
        // 2 mock步骤
        mockStep();
        // 3 执行操作
        ResponseMessage result = hotelController.detail(id);
        System.out.println(new Gson().toJSON(result));
        assertEquals(0, (int) result.getCode());
    }
    private void mockStep() {
        when(hotelService.detail(anyInt())).thenReturn(ResponseMessage.success());
    }
    private void ininParams(Integer type) {
        switch(type){
            case 1:
                id=17317;
                break;
            case 2:
                id=2;
                break;
            default:
                break;
        }
    }
}

4 模拟私有方法和静态方法


@PrepareForTest(OrderServiceImpl.class)  // 需要调用私有或者静态方法的类
public class OrderControllerTest extends TestBase {
    private OrderServiceImpl orderServiceImpl; //需要调用私有或者静态方法时,不能使用@Mock,还需要@before初始化属性
    @Mock
    private OrderMapper orderMapper;
    @Mock
    private RestTemplateUtil restTemplateUtil;
    private Integer orderId;
    private String wxcid;
    @Before
    public void init(){
        //处理私有方法模拟实例
        orderServiceImpl = PowerMockito.spy(new OrderServiceImpl()); //使用spy模拟的需要手动注入属性,因为什么都没有
        ReflectionTestUtils.setField(orderController, "iOrderService", orderServiceImpl);
        ReflectionTestUtils.setField(orderServiceImpl, "orderMapper", orderMapper);
        ReflectionTestUtils.setField(orderServiceImpl, "restTemplateUtil", restTemplateUtil);
    }
    //纯mock测试,不加载springContext,执行mock操作,必须mock步骤,不会真实调用
    @InjectMocks
    private OrderController orderController=new OrderController();
    @Test
    public void cancelTest(){
        System.out.println("test start.....");
        // 1 构造参数
        ininParams();
        // 2 mock步骤
        mockStep();
        // 3 执行操作
        ResponseMessage cancel = orderController.cancel(wxcid, orderId);
        assertEquals(0,(int)cancel.getCode());
    }
    private void mockStep() {
        Order order = new Order();
        order.setStatus(2);
        when(orderMapper.getOrderByOrderId(anyInt())).thenReturn(order);
        when(orderMapper.updateStatus(anyInt(),anyInt())).thenReturn(2);
        jsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("code",0);
        when(restTemplateUtil.postToCri(anyString(),anyString(),any())).thenReturn(jsonObject);
        //处理私有方法,必须用这种写法
        try {
            PowerMockito.doNothing().when(orderServiceImpl, "returnTicketTouser", anyString(),any());
            PowerMockito.doReturn(ErrorCode.SUCCESS).when(orderServiceImpl, "refoundAndGetCode", any(),any(),any(),any());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private void ininParams() {
        wxcid="57af462dff475fe4644de32f08406aa8";
        orderId=25864;
    }
}

注意:

如果是分模块项目,springboot项目的启动类只能有一个,即需要把其他service,dao,common模块的启动类的启动注解给注释掉,否则测试启动会报错

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: 如何使用Mockito调用静态方法和void方法

本文链接: https://www.lsjlt.com/news/130302.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用Mockito调用静态方法和void方法
    一、mock 静态方法 mockito库并不能mock静态方法,需要依赖powermock 第一步:给类添加注解 // 静态类优先加载,所以需要提前告诉powermock哪些静态...
    99+
    2024-04-02
  • java静态和非静态方法怎么调用
    在Java中,静态方法和非静态方法的调用方式有所不同。 静态方法调用: 静态方法可以直接通过类名来调用,不需要创建类的实例。例如:...
    99+
    2024-04-02
  • java中静态方法如何调用
    在Java中,可以通过以下两种方式来调用静态方法:1. 使用类名调用静态方法:可以直接通过类名来调用静态方法,不需要创建类的实例。语...
    99+
    2023-09-14
    java
  • php如何使用静态方法
    本篇内容介绍了“php如何使用静态方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在php中,通过static关键字修饰的成员方法被称为静...
    99+
    2023-06-20
  • JavaScript——为什么静态方法不能调用非静态方法
    个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,正逐渐往全干发展 📃个人状态: 研发工程师,现效力于中国工业软件事业 🚀人生格言: 积跬步至千里,积小...
    99+
    2023-08-30
    javascript 前端
  • C#中如何使用静态方法
    C#中如何使用静态方法,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。C#静态方法使用中遇到的问题:在源码工程中几乎没有看到什么静态方法,但是在Ms的SQLHelper中几乎全部...
    99+
    2023-06-17
  • c#怎么调用静态方法
    在 c# 中,调用静态方法可以通过两种方式:1. 使用类名直接调用;2. 使用类型名称 + 双冒号调用。 如何在 C# 中调用静态方法 什么是静态方法? 静态方法是不属于任何特定对象实...
    99+
    2024-05-12
    c#
  • c#静态方法怎么调用
    非常抱歉,由于您没有提供文章标题,我无法为您生成一篇高质量的文章。请您提供文章标题,我将尽快为您生成一篇优质的文章。...
    99+
    2024-05-14
  • 如何在javascript中使用静态方法
    这篇文章将为大家详细讲解有关如何在javascript中使用静态方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。JavaScript的特点1.JavaScript主要用来向HTML页面添加...
    99+
    2023-06-14
  • javascript中如何使用class静态方法
    这篇文章将为大家详细讲解有关 javascript中如何使用class静态方法,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。类相当于实例的原型, 所有在类中...
    99+
    2024-04-02
  • 如何在java中使用静态方法
    如何在java中使用静态方法?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编程语言的代表,实现了面向...
    99+
    2023-06-14
  • kotlin怎么调用java静态方法
    在 Kotlin 中调用 Java 的静态方法非常简单,只需要使用 Java 类的全限定名加上静态方法名即可。例如,假设有一个 Ja...
    99+
    2024-04-02
  • C#静态方法的使用
    一、简介 使用了static 修饰符的方法为静态方法,反之则是非静态方法。 静态方法是一种特殊的成员方法,它不属于类的某一个具体的实例,而是属于类本身。所以对静态方法不需要...
    99+
    2024-04-02
  • Python中静态方法,类方法,属性方法使用方法
    目录1.静态方法2.类方法3.静态方法与类方法总结4.属性方法1.静态方法 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普...
    99+
    2024-04-02
  • 怎么使用Java方法调用解析静态分派和动态分派
    这篇“怎么使用Java方法调用解析静态分派和动态分派”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用Java方法调用解...
    99+
    2023-07-02
  • java中什么是静态方法和非静态方法
    本篇文章为大家展示了java中什么是静态方法和非静态方法,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。常用的java框架有哪些1.SpringMVC,Spring Web MVC是一种基于Java的...
    99+
    2023-06-14
  • Python的类方法与静态方法的使用
    本篇内容主要讲解“Python的类方法与静态方法的使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Python的类方法与静态方法的使用”吧!在Python语言中有如下3种方法:成员方法类方法(...
    99+
    2023-06-15
  • Powermock静态方法怎么使用
    本篇内容主要讲解“Powermock静态方法怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Powermock静态方法怎么使用”吧!Mockito 很强大, 但是它不支持静态方法.所以, ...
    99+
    2023-06-04
  • JVM 方法调用之静态分派(详解)
    分派(Dispatch)可能是静态也可能是动态的,根据分派依据的宗量数可分为单分派和多分派。这两种分派方式的两两组合就构成了静态单分派,静态多分派,动态单分派,动态多分派这4种组合。本章讲静态分派。1、静态分派所有依赖静态类型来定位方法执行...
    99+
    2023-05-31
    jvm 方法调用 静态
  • php中的静态属性和静态方法怎么用
    这篇文章主要介绍“php中的静态属性和静态方法怎么用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“php中的静态属性和静态方法怎么用”文章能帮助大家解决问题。在php中,通过static关键字修饰的...
    99+
    2023-06-26
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作