网页优化与网站优,百度免费注册,上海传媒公司简介,wordpress 模板 使用Java 新手入门#xff1a;Java单元测试利器#xff0c;Mock详解_java mock-CSDN博客
这个是典型的before when assert三段式#xff0c;学一下单测思路 这个没有动态代理#xff0c;所以是直接class(对比下面) Jmockit使用笔记_增加代码覆盖率_覆盖try catch_使用new Mock…Java 新手入门Java单元测试利器Mock详解_java mock-CSDN博客
这个是典型的before when assert三段式学一下单测思路 这个没有动态代理所以是直接class(对比下面) Jmockit使用笔记_增加代码覆盖率_覆盖try catch_使用new MockUp私有方法-CSDN博客 new mock up:
Jmockit使用MockUp控制被注入Service的方法_mockup使用教程-CSDN博客
默认方法的含义
在 JMockit 中当一个类的依赖如 链接的UserService被注入时如果没有为该依赖的某个方法设置具体的行为JMockit 会提供一个默认实现。这个默认实现通常是
对于 返回值类型 的方法 返回值类型是 int 或其他基本类型时返回其默认值如 0、false 等。返回值类型是对象时返回 null。对于 void 方法 不执行任何实际逻辑相当于一个空实现。
由于 userService 是被 JMockit 模拟的setUserId 方法的默认实现 不会修改 orderInfo 的 userId 属性。因此
orderInfo.getUserId() 始终为 null 模拟类里面的方法:
方式一:使用new Expectations()
Test
public void getOrderInfo1() {new Expectations() {{userService.setUserId((OrderInfo) any);result new DelegateOrderInfo() {void delegate(OrderInfo orderInfo) {orderInfo.setUserId(ZHANGSAN123); // 模拟方法逻辑}};}};OrderInfo result testService.getOrderInfo(123);// 验证结果Assert.assertEquals(ZHANGSAN123, result.getUserId());
}
这部分代码是 JMockit 的 Expectations 定义主要用来模拟依赖对象 userService 的行为。 userService.setUserId((OrderInfo) any) 声明当 userService 的 setUserId 方法被调用时不管传入的参数是什么(OrderInfo) any都会执行后续的行为。 result new DelegateOrderInfo() 为被调用的方法定义了一个代理逻辑即模拟实现。这里 Delegate 是 JMockit 提供的功能用来自定义方法的执行逻辑。 代理逻辑void delegate(OrderInfo orderInfo) 传入的 orderInfo 对象是调用 setUserId 方法时的参数。在代理逻辑中直接对 orderInfo 的 userId 属性赋值为 ZHANGSAN123。 解读: userService.setUserId((OrderInfo) any) 定义了 userService 的 setUserId 方法在接收到任何 OrderInfo 对象作为参数时会执行以下逻辑。 result new DelegateOrderInfo() { ... }通过 Delegate 为方法提供了具体的代理逻辑 当 setUserId 被调用时不会执行真实的实现而是执行代理逻辑直接将 orderInfo.userId 设置为 ZHANGSAN123。
Expectations 如何影响依赖对象
示例
OrderInfo result testService.getOrderInfo(123); 依赖方法调用 testService.getOrderInfo 会调用 userService.setUserId(orderInfo)。 方法替换 因为用 Expectations 模拟了 setUserId 方法实际调用的不是 UserService 的真实方法而是 Expectations 中定义的代理逻辑。 逻辑执行 在代理逻辑中将 orderInfo.userId 设置为 ZHANGSAN123。 结果返回 通过修改后的 OrderInfo 对象返回给调用方。
基本原理Expectations 是 JMockit 提供的一种基于 声明式 的方式用于定义某个依赖对象的方法行为。
通过在测试代码中定义具体的行为测试框架根据定义的规则动态返回结果或执行逻辑。对特定实例生效不影响该类的其他实例。 方式2:使用new mockup()推荐更easy
new MockUpUserService(userService.getClass()) {Mockpublic void setUserId(OrderInfo orderInfo) {orderInfo.setUserId(zhangsan123);}
};基本原理MockUp 是 JMockit 提供的一种方式用于在运行时修改类的方法实现。
可以直接为某个类的具体方法编写新的实现类似于 重写方法。使用 Mock 注解标记需要模拟的方法。 注意:
/*** author xinruoxiangyang9010* 这里的参数必须是:userService.getClass()* 如果写成UserService.class则Mock里面的方法不生效*/
new MockUpUserService(userService.getClass())
1. UserService.class
表示类级别的代理 当你使用 new MockUpUserService() 或 new MockUpUserService(UserService.class) 时JMockit 会针对 UserService 类本身 进行代理。 它的效果是全局生效影响所有实例。但是如果在运行时你注入的是 userService 的一个动态代理对象比如 Spring 的动态代理机制生成的对象代理逻辑不会直接生效。
2. userService.getClass()
表示对象所属的动态类型userService.getClass() 返回的是 userService 实际运行时的类型。 如果 userService 是被 Spring 动态代理如 CGLIB 或 JDK 动态代理生成的对象那么 userService.getClass() 返回的就是这个动态代理类。MockUp 会针对这个动态代理类生效从而让 Mock 标注的方法在调用时起作用。
在实际项目中特别是使用 Spring 框架时Autowired 注入的 userService 很可能是一个动态代理对象而不是直接的 UserService 实例。
假设 userService 是通过 Spring 注入的动态代理对象
System.out.println(userService.getClass()); // 输出类似 com.example.UserService$$EnhancerBySpringCGLIB$$12345