PowerMock注解PowerMockIgnore的使用方法

2023-05-16

故事要从一个异常开始,某天我在开发一个加密、解密特性,算法使用的是3DES,样例代码如下。

package org.jackie.study.powermock;

import java.io.UnsupportedEncodingException;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author Jackie
 *
 */
public class TripleDESAlgorithm {
    private static final String ALGORITHM = "DESede";

    public static byte[] encrypt(String cryptKey, byte[] src) {
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(cryptKey), ALGORITHM);
            Cipher c1 = Cipher.getInstance(ALGORITHM);
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] decrypt(String cryptKey, byte[] src) {
        try {
            SecretKey deskey = new SecretKeySpec(build3DesKey(cryptKey), ALGORITHM);
            Cipher c1 = Cipher.getInstance(ALGORITHM);
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    static byte[] build3DesKey(String keyStr) throws UnsupportedEncodingException {
        byte[] key = new byte[24];
        byte[] temp = keyStr.getBytes("UTF-8");
        if (key.length > temp.length) {
            System.arraycopy(temp, 0, key, 0, temp.length);
        } else {
            System.arraycopy(temp, 0, key, 0, key.length);
        }

        return key;
    }
}
用来验证这个算法类的单元测试代码工作正常,运行结果显示上述加密、解密代码逻辑正确,没有错误,测试代码如下。

package org.jackie.study.powermock;

import org.junit.Assert;
import org.junit.Test;

public class TripleDESAlgorithmTest {

    @Test
    public void test() throws Exception {
        String key = String.valueOf(System.currentTimeMillis()) + "jackie";
        byte[] encrypted = TripleDESAlgorithm.encrypt(key, "helloworld".getBytes("UTF-8"));
        byte[] decrypted = TripleDESAlgorithm.decrypt(key, encrypted);
        Assert.assertEquals("helloworld", new String(decrypted, "UTF-8"));
    }
}
但当我使用单元测试代码来验证特性代码功能是否正常时,但恼人的事情发生了,测试代码抛出了诡异的异常,如下。

java.lang.ClassCastException: com.sun.crypto.provider.DESedeCipher cannot be cast to javax.crypto.CipherSpi
	at javax.crypto.Cipher.chooseProvider(Cipher.java:845)
	at javax.crypto.Cipher.init(Cipher.java:1213)
	at javax.crypto.Cipher.init(Cipher.java:1153)
	at org.jackie.study.powermock.TripleDESAlgorithm.encrypt(TripleDESAlgorithm.java:23)
	at org.jackie.study.powermock.SubscriberTest.testSayHello(SubscriberTest.java:19)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
	at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:310)
异常信息比较长,这里仅截取了一部分,但是可以说明问题。

业务代码和测试代码如下。

// 业务代码
package org.jackie.study.powermock;

public class Subscriber {
    private String name;
    // 解密收到的加密信息
    public String sayHello(String name, byte[] message) throws Exception
    {
        byte[] realMessage = TripleDESAlgorithm.decrypt(name, message);
        
        if (realMessage != null)
        {
            this.name = name;
            return new String(realMessage, "UTF-8");
        }
        return null;
    }

    public String getName() {
        return name;
    }
}
// 测试代码
package org.jackie.study.powermock;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest
public class SubscriberTest {
	@Test
	public void testSayHello() throws Exception {
	    byte[] encryptMessage = TripleDESAlgorithm.encrypt("jackie", "hello world!".getBytes("UTF-8"));
	    
	    Subscriber subscriber = new Subscriber();
	    subscriber.sayHello("jackie", encryptMessage);
	    Assert.assertEquals("jackie", subscriber.getName());
	}
}

异常很让人伤脑筋,因为反编译类com.sun.crypto.provider.DESedeCipher可以发现,这个算法实现类的确是javax.crypto.CipherSpi的子类,类转换失败实在是不应该。通常情况下如果出现ClassCastException,除了确实是类型不匹配外,还有一种可能即是两个类的ClassLoader不同,导致JVM认为这两个类没有关联。想到这里,这个问题基本上就有点思路了,因为PowerMock的工作原理即是使用自定义的类加载器来加载被修改过的类,从而达到打桩的目的,这里会不会是这个原因呢?

求助Google大师,发现在官网上有如下一段话。根据提示,我在测试类SubscriberTest前面加上了@PowerMockIgnore({"javax.crypto.*"}),保存之后重新运行测试代码,发现异常不再抛出,问题得到了解决。

The reason is that the XML framework tries to instantiate classes using reflection and does this from the thread context classloader (PowerMock's classloader) but then tries to assign the created object to a field not loaded by the same classloader. When this happens you need to make use of the @PowerMockIgnore annotation to tell PowerMock to defer the loading of a certain package to the system classloader. What you need to ignore is case specific but usually it's the XML framework or some packages that interact with it. E.g. @PowerMockIgnore({"org.xml.*", "javax.xml.*"}).

从上述描述中可以得到的信息是,假如待测试类中使用到了XML解析相关的包和类,那么测试类前同样需要增加@PowerMockIgnore({"org.xml.*", "javax.xml.*"}),消除类加载器引入的ClassCastException。





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PowerMock注解PowerMockIgnore的使用方法 的相关文章

  • switch-case使用方法

    switch case 语句判断一个变量与一系列值中某个值是否相等 xff0c 每个值称为一个分支 switch case 语句语法格式如下 xff1a switch语句应用举例1 xff1a public class VariableTe
  • setw()使用方法

    1 setw xff08 int n xff09 只是对直接跟在 lt lt 后的输出数据起作用 xff0c 而在之后的 lt lt 需要在之前再一次使用setw xff1b xff08 Sets the number of charact
  • wait_event_interruptible_locked的使用方法

    wait event interruptible locked interface New wait event interruptible exclusive locked irq macros added They work just
  • 窨井液位计(下水道液位计)的分类

    窨井液位计又称下水道液位计 是应用在市政管网监测集水井 雨水井 污水井 观察井等测量水位变化的仪表 根据原理不同可分为 压力式 雷达式和超声波式3种 通过传感器测量液位数值 利用无线远传的方式上传到数据平台 实现对井下水位实时监测的目的 压
  • 农业土壤墒情监测系统解决方案

    一 方案概述 土壤墒情监测系统能够实现对土壤墒情 土壤湿度 的长时间连续监测 用户可以根据监测需要 灵活布置土壤水分传感器 也可将传感器布置在不同的深度 测量剖面土壤水分情况 系统还提供了额外的扩展能力 可根据监测需求增加对应传感器 监测土
  • 河道堤防GNSS位移监测系统

    一 方案背景 我国河系众多 海岸线漫长 在江边 河边 海边修筑修筑着几万公里的提防设施保卫着沿江 沿海居民的生命安全 也保卫着经济发展的累累硕果 近年来 因台风暴雨造成河道堤坝决堤 产生的经济损失越来越大 各对方对防洪堤 海堤的安全检查要求
  • 如何让 Powermock 与 Dexmaker 配合使用

    我正在尝试合并动力模拟使用以下 build gradle 配置作为我的 Android 测试的依赖项 dependencies compile com android support appcompat v7 21 0 androidTes
  • PowerMock 无法与 JAXB Unmarshal 一起使用

    我正在创建一个测试用例 其中输入 xml 并将其解组以继续处理 我正在尝试使用 PowerMock 但我不断收到 javax xml bind UnmarshalException unexpected element uri http w
  • 如何模拟修改私有变量的私有方法?

    如何模拟修改私有变量的私有方法 class SomeClass private int one private int second public SomeClass public int calculateSomething comple
  • EclEmma 代码覆盖率插件和 PowerMockRunner

    我在Eclipse中使用EclEmma插件时遇到了问题 当我使用注释时它不显示代码覆盖率 RunWith通过 PowerMockRunner class 作为一个论点 如果使用 MockitoJUnitRunner class 一切安好 等
  • 在测试类中模拟私有静态最终变量

    我想测试的类中有一些私有静态最终字段 就像下面这样 public class ClassToTest private static final Myclass myclass MyClassFactory getMyClass type f
  • 无法在仪器测试中模拟静态方法

    我很难模拟仪器的静态方法 Espresso 测试 对于模拟对象 我正在使用Mockito 但是由于Mockito无法模拟静态方法 我正在使用Powermock在它的上面 这对于在 JVM 机器上运行的测试来说效果很好 但是对于 UI 测试来
  • 如何使用mockito/powermock模拟Google的地理编码API请求?

    我想使用mockito powermock对该方法进行单元测试 Service public class GoogleApiService private static final Logger logger LoggerFactory g
  • 使用 Powermock 模拟类的构造函数时出现 ExceptionInInitializerError。如何修复它?

    这是我的案例 我有一个 AbstractController 类 它有一个子类Controller 在 AbstractController 的方法之一中 实例化了一个新的 ApplicationLock 我想在为控制器编写 ut 时模拟
  • 如何验证是否在被测系统(不是模拟)上调用方法

    我正在尝试编写一个单元测试 需要确认是否调用了某个方法 我正在使用 JUnit Mockito 和 PowerMock public class Invoice protected void createInvoice random stu
  • 使用骆驼的电源模拟时出现问题

    由于我必须模拟静态方法 所以我使用电源模拟测试我的应用程序 我的应用程序使用 骆驼2 1 2 我定义路线XML被读取的是骆驼泉语境 没有出现任何问题的时候Junit单独用于测试 使用电源模拟时 我收到帖子末尾列出的错误 我还列出了使用的 X
  • 在 Junit4 (PowerMock) 中实现模拟时的依赖关系

    下面是我的 JUnit 测试用例 import static org junit Assert assertEquals import static org junit Assert assertNull import static org
  • 如何使用 PowerMock 仅模拟 LocalDate.now()

    我只想嘲笑now of LocalDate使用PowerMock 似乎忽略了thenReturn value java lang AssertionError Expected 2008 Actual 2017 测试设置 PrepareFo
  • Robolectric 和 Powermock 之间的类加载冲突

    我正在尝试编写一个需要两者的测试机器人电动2 2 和电源模拟 因为被测试的代码依赖于一些 Android 库和第三方库以及我需要模拟的最终类 鉴于我被迫通过以下方式使用 Robolectric 测试运行程序 RunWith Robolect
  • 从 JDK 1.6 迁移到 JDK 1.7 的 PowerMockito 测试出现约束违规

    我们有一些测试在 JDK 1 6 上运行良好 我们现在正在转向 JDK 1 7 这些测试在 Eclipse 中运行良好 当我们从 Ant 构建运行这些测试时 我们会看到如下错误 junit framework TestListener ad

随机推荐

  • JAVA常用类

    Object类 Object类是类层次结构的根 xff0c 每个类都可以将Object作为超类 所有类都直接或者间接的继承该类 Object只有无参构造方法 Math类 包含执行基本数学运算的方法 Random类 伪随机数 java uta
  • Collections类 [Java]

    Collections工具类 Collections是一个操作Collection集合和Map集合的工具类 Collections不仅仅是操作Collection集合 还可以操作Map集合 Collection和Collections有什么
  • 我阿里P7了解到的Android面试的一些小内幕!已拿offer

    前言 这些题目是网友去百度 小米 乐视 美团 58 猎豹 360 新浪 搜狐等一线互联网公司面试被问到的题目 熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率 欢迎一线公司员工以及网友提交面试题库 xff0c 欢迎留言 网上的都是按
  • 7月编程排行榜来啦!这次有何新变化?

    每月编程排行榜可能会迟到 xff0c 但永远不缺席 7月的编程排行榜已出 xff0c 接下来一起看看有哪些看点吧 Tiobe编程排行榜前20名 Tiobe编程排行榜Top 10趋势 TIOBE Index编程社区指数是编程语言流行度的一个指
  • 操作系统 记录型信号量实现生产者消费者问题(完整代码)

    问题描述 用信号量模拟生产者 消费者问题的过程 生产者和消费者两个线程共享同一个缓冲区 xff0c 生产者不断向缓冲区中添加产品 xff0c 消费者从缓冲区中消费产品 要保证缓冲区满了之后生产者不能再继续添加产品 xff0c 需要等消费者至
  • 制版经验分享—使用AD18

    文章目录 前言一 封装二 走线三 注意细节四 制版流程五 制版细节总结 前言 在做一些培训题目时 xff0c 由于时间有限制 xff0c 在外面开板会花费好几天的制作和快递时间 xff0c 所以有时候就需要自己制版 xff0c 在这里我记录
  • Java打印九九乘法表

    1 使用双重for循环打印九九乘法表 Java源代码如下 xff1a for int i 61 0 i lt 61 9 i 43 43 for int j 61 1 j lt 61 i j 43 43 System out print i
  • 解决selenium打开Chrome浏览器自动退出的问题

    好不容易安装好selenium和对应的浏览器驱动器后终于可以运行程序了 xff0c 结果发现一运行程序后浏览器打开就自动退出了 xff0c 但是我在Python代码中并没有写driver quit 方法 xff0c 上网查了查发现原来是我的
  • 在Java应用中嵌入sshd服务

    这个应用需要依赖apache mina的子项目sshd xff0c 项目主页http mina apache org sshd project index html xff0c 当前版本号为0 8 0 这里的sshd和Linux下的sshd
  • openssl开发库安装时的踩坑指南

    序 前几天用linux编译一个提权脚本的时候报错 openssl opensslv h 没有那个文件或目录 的问题 无论如何也解决不了 xff0c 这下我记录一个踩坑指南防止下一个人掉进坑里 操作 总体介绍 首先介绍一下 xff0c 这个报
  • 性能测试脚本用例【模板】

    产品名称Product name 密级Confidentiality level 秘密 产品版本Product version Total 12pages 共12页 性能测试脚本用例 仅供内部使用 拟制 日期 xff1a 审核 日期 xff
  • Java常见的集合类

    我们常见的Java集合类有List Set Map List 1 接口可以被继承 2 接口可以被多次实现 3 List和ArrayList package List import java util ArrayList import jav
  • WIN7我的电脑右键管理打不开

    问题现象 xff1a 我的电脑右键点击管理无法正常打开 xff0c 会弹出下面的报错信息 首先打开注册表 xff0c 打开运行 xff0c 输入regedit 选择路径 xff1a HKEY LOCAL MACHINE SOFTWARE C
  • LIKE的用法

    我们来谈谈关于like运算符的理解 xff1a 下面是like的语法 xff0c 以后使用到like运算符的都必须根据这个语法使用 LIKE 运算符是用来匹配通配符指定模式的文本值 如果搜索表达式与模式表达式匹配 xff0c LIKE 运算
  • 从0开始详细安装archlinux(UEFI启动)

    隔了一周没更新 xff0c 前阵子把电脑windows卸了装了个archlinux xff0c 不得不说arch是真的香 xff0c 但是坑也是真的多 xff0c 刚踩完所有的坑 xff0c 滚回来写blog了 注 xff1a 本贴为UEF
  • archlinux开机无法联网问题,以及安装archlinuxcn和yay管理器

    前一篇已经安装完了archlinux系统 xff0c 不过真正难的其实并不是安装 xff0c 你的路现在才开始 xff0c 哈哈 添加用户 建议 xff0c 不然使用登录管理器的时候不支持root用户 span class token fu
  • archlinux安装kde桌面和sddm登录管理器

    前几篇已经配置好了archlinuxcn软件仓库 xff0c 网络和nvidia驱动 xff0c 现在来给你的archlinux安装一个kde桌面 xff08 kde玩法有很多 xff0c 可以自己去搜一搜美化教程 xff09 xff0c
  • Spring框架学习

    目录 目录 学习内容 xff1a IoC java中创建对象有哪些方式 xff1a ioc的体现 xff1a DI 是ioc的技术实现 spring的第一个核心功能 ioc Spring 八大模块 Spring的特点 xff1a Sprin
  • CenOs6.7不能使用yum命令

    因为官方不维护了所以 先用更换源 wget O etc yum repos d CentOS Base repo https mirrors aliyun com repo Centos vault 6 10 repo https deve
  • PowerMock注解PowerMockIgnore的使用方法

    故事要从一个异常开始 xff0c 某天我在开发一个加密 解密特性 xff0c 算法使用的是3DES xff0c 样例代码如下 package org jackie study powermock import java io Unsuppo