【发布时间】:2015-02-24 14:50:51
【问题描述】:
在我当前的项目(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());
}
powermock 页面自 2009 年以来已有 bug,但没有修复和解决方法。 (回到 32Bit 是无稽之谈,因为这些方法在没有 powermock 的情况下工作)那么有人知道如何解决这个问题吗?
更新一:切换到 32 位是没有选择的,除此之外这不是问题。如果我不使用 PowerMock,每个测试都可以在我的 64 位 JVM 中完美运行...
更新二:好的,这里是请求的信息
更新三:扩展类
-
要测试的类
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); } } -
测试用例:
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(); } } -
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>
因此,如果您评论该行:
//@RunWith(PowerMockRunner.class)
这是工作。如果取消注释,则会抛出上述错误(再次!)
【问题讨论】:
-
部分问题似乎是powermock的不同类加载器。如果我添加 @PowerMockIgnore({"com.sun.imageio.*"}) 似乎可以更进一步,但它仍然无法正常工作......
-
我相信错误中的方法是本机方法。你想在这里达到什么目的?模拟 ImageIO?
-
我想模拟一个私有方法 - 所以我为此添加了 powermock。之后,其他没有 powermock 成功的现有测试应该像以前一样工作 - 这就是我想要实现的......
-
您可能会考虑使用 JMockit。它只是一个库,无论使用接口还是类,使用起来都非常简单且一致,我现在更喜欢它,而不是我以前最喜欢的 Mockito。 JMockit 使用 Java6 的字节码检测而不是 java.lang.reflect.Proxy 和 CGLIB。见jmockit.org
-
您能否提供更多信息(依赖关系树,完整的测试类)。根据您发布的代码,我使用 easymock 3.2、powermock 1.5.6、junit 4.4 创建了一个测试 (PowerMockRunner),它可以工作。
标签: java powermock easymock javax.imageio