Lon*_*zak 2 java easymock powermock javax.imageio
在我的当前项目(jdk 1.6.0)中添加了powermock(1.5.6与Easymock 3.2的组合)之后,我在测试方法中遇到了一些测试失败,这些测试方法之前完全正常:
java.lang.UnsatisfiedLinkError:com.sun.imageio.plugins.jpeg.JPEGImageReader.initReaderIDs(Ljava/lang/Class; Ljava/lang/Class; Ljava/lang/Class;)V
以下代码失败:
BufferedImage img = null;
try {
img = ImageIO.read(this.getClass().getResourceAsStream("/example.jpg"));
}
catch (IOException e) {
fail(e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)
powermock页面已经有一个2009年的错误,但没有修复,没有解决方法.(回到32Bit是无稽之谈,因为这些方法没有电动摇摆工作)所以有人知道如何解决这个问题吗?
更新I:切换到32位是没有选择,除此之外,这不是问题.如果我不使用PowerMock,每个测试都在64Bit JVM中完美运行......
更新II:这里是请求的信息
更新III:扩展课程
要测试的类
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import javax.imageio.ImageIO;
import sun.security.x509.CertificateIssuerName;
import sun.security.x509.CertificateSubjectName;
import sun.security.x509.X500Name;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;
public class App {
private X509Certificate certificate = null;
public ByteArrayOutputStream readImage() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BufferedImage img = null;
try {
img = ImageIO.read(this.getClass().getResourceAsStream("/example.jpg"));
ImageIO.write(img, "png", baos);
}
catch (IOException e) {
e.printStackTrace();
}
return baos;
}
public String readCertificate() throws Exception{
this.certificate = generateCertificate();
return this.certificate.getIssuerX500Principal().getName();
}
private static X509Certificate generateCertificate() throws GeneralSecurityException, IOException{
X509CertInfo info = new X509CertInfo();
X500Name owner = new X500Name("CN=example.net");
info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner));
info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner));
return new X509CertImpl(info);
}
}
Run Code Online (Sandbox Code Playgroud)测试用例:
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest(App.class)
@PowerMockIgnore("javax.imageio.*, javax.security.*")
public class AppTest {
@Test
public void testApp(){
App test = new App();
Assert.assertNotNull(test.readImage());
Assert.assertEquals(284506, test.readImage().size());
}
@Test
public void testCertificate() throws Exception{
App test = new App();
test.readCertificate();
}
}
Run Code Online (Sandbox Code Playgroud)Maven依赖:
<dependencies>
<!-- TEST -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.5.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>1.5.6</version>
<scope>test</scope>
</dependency>
Run Code Online (Sandbox Code Playgroud)
所以,如果你评论这条线:
//@RunWith(PowerMockRunner.class)
它是有效的.如果取消注释,则抛出上述错误(再次!)
Rog*_*rio 10
解决方案是告诉PowerMock忽略与其自定义类加载器冲突的所有JRE类.也就是说,将以下注释添加到测试类:
@PowerMockIgnore({"javax.imageio.*", "javax.security.*"})
Run Code Online (Sandbox Code Playgroud)
(注意,注释的value属性采用正则表达式数组 ;它不支持单个字符串中的多个逗号分隔表达式.)
需要解释为什么需要这样做
App调用时javax.imageio.ImageIO,它最终尝试加载并初始化内部类com.sun.imageio.plugins.jpeg.JPEGImageReader,然后内部类尝试com.sun.imageio从调用者类加载器加载一些其他类; 和JPEGImageReader- 可能它尝试加载一些本机库以及).| 归档时间: |
|
| 查看次数: |
1587 次 |
| 最近记录: |