我需要帮助以下事情,
我必须使用PowerMock / Mockito编写一个Junit,用于调用外部jar中存在的最终类的静态方法。
我需要编写JUnit测试的方法是:
public class SomeClass {
private PrivateKey privateKeyFromPkcs8(String privateKeyPem) throws IOException {
Reader reader = new StringReader(privateKeyPem);
Section section = PemReader.readFirstSectionAndClose(reader, "PRIVATE KEY");
if (section == null) {
throw new IOException("Invalid PKCS8 data.");
}
byte[] bytes = section.getBase64DecodedBytes();
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
try {
KeyFactory keyFactory = SecurityUtils.getRsaKeyFactory();
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
} catch (NoSuchAlgorithmException exception) {
} catch (InvalidKeySpecException exception) {
}
throw new IOException("Unexpected exception reading PKCS data");
}
}
在上面的代码中,PemReader
是最后一个类,而readFirstSectionAndClose(reader, "PRIVATE KEY")
是PemReader
中的静态方法。
我尝试编写下面显示的测试,但调试时Section object(section)
显示为null。也许实际的代码(PemReader.readFirstSectionAndClose(reader, "PRIVATE KEY")
)被调用而不是模拟。
@RunWith(PowerMockRunner.class)
@PrepareForTest({SomeClass.class,PemReader.class})
public class SomeClassTest {
@InjectMocks
SomeClass mockSomeClass;
@Mock
private Reader mockReader;
@Mock
private Section mockSection;
@Test
public void testPrivateKeyFromPkcs8() throws Exception {
PowerMockito.mockStatic(PemReader.class);
Mockito.when(PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY")).thenReturn(mockSection);
assertNotNull(mockSomeClass.privateKeyFromPkcs8(dummyPrivateKey));
}
}
请使用powermockito / mockito
帮我写一个Junit答案 0 :(得分:0)
你必须准备最终的静态类。
以下是使用JUnit的PowerMock注释的示例:
@RunWith(PowerMockRunner.class)
@PrepareForTest({PemReader.class})
public class PemReaderTest {
@Mock
private Reader mockReader;
@Mock
private Section mockSection;
@Test
public void testMockingStatic() {
PowerMockito.mockStatic(PemReader.class);
Mockito.when(PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY")).thenReturn(mockSection);
Assert.assertEquals(mockSection, PemReader.readFirstSectionAndClose(mockReader, "PRIVATE KEY"));
}
}
为了完整起见,这里是PemReader
:
public final class PemReader {
public static Section readFirstSectionAndClose(Reader reader, String key) {
return null;
}
}
上述测试通过以下版本:
4.12
2.7.19
1.7.0
更新1 :根据您更新的问题。如果您只是进行此更改,您的测试用例将通过(或至少PemReader.readFirstSectionAndClose
上的调用将返回一些内容):
Mockito.when(PemReader.readFirstSectionAndClose(
Mockito.any(Reader.class),
Mockito.eq("PRIVATE KEY"))
).thenReturn(mockSection);
当前测试用例中此指令的版本依赖于代码传入StringReader
的{{1}}与测试用例提供的模拟readFirstSectionAndClose
之间的相等匹配。这些并不是平等的。因此,不满足模拟调用的期望,并且不会返回Reader
。
一些不相关的笔记:
mockSection
中包含SomeClass.class
,您只需要在该注释中包含要模拟的类,因为@PrepareForTest
是您要尝试的类测试该课程不需要嘲笑。SomeClass
实例@InjectMocks
有点奇怪,因为SomeClass
没有(模拟提供的)模拟注入它:)你可以用{{1}替换此声明} SomeClass
具有私有范围,因此无法从SomeClass someClass = new SomeClass();
进行测试(或以任何方式调用)。