public static String generateSaltString() {
SecureRandom random = new SecureRandom();
byte[] salt = random.generateSeed(12);
return byteToBase64(salt);
}
想知道如何使用 Junit 为这种方法编写测试用例。有什么建议吗?
首先是 new SecureRandom() 可能会非常慢,因此您可能需要缓存它。看看这个答案和这个答案。
我会重构你的代码如下
public class DoRandomStuff {
private RandomUtil randomUtil;
public DoRandomStuff(RandomUtil randomUtil) {
this.randomUtil = randomUtil;
}
public String generateSaltString() {
byte[] salt = randomUtil.generateSeed(12);
return byteToBase64(salt);
}
public String byteToBase64(byte[] salt) {
// Do salt generation logic here
return null;
}
generateSeed 看起来像一个实用方法调用,因此它可以进入一个看起来像这样的类 RandomUtil
class RandomUtil {
private SecureRandom random = new SecureRandom();
public byte[] generateSeed(int seed) {
return random.generateSeed(seed);
}
}
现在您的 DoRandomStuff 测试类将很容易编写。使用 Mockito 等测试框架注入模拟的 randomUtil。使 mockedRandomUtil.generateSeed(int) 方法返回一个固定数字。您的测试实际上是为了检查 byteToBase64() 方法是否正在做它应该做的事情。现在,您的测试用例有了一个确定的数字。您可以将 SecureRandom 在您的测试类中生成的各种数字作为单独的测试用例提供,以检查 byteToBase64() 结果。另外,您的随机数生成代码现在与您的 base64 代码分离。
希望它有所帮助。
我会测试结果是否不为空,然后多次调用该方法并比较结果以显示每次调用都返回不同的值。
但请记住:这并没有说明您的结果随机性的质量!
@Test
public void testGenerateSaltString() {
String salt1 = YourClass.generateSaltString();
String salt2 = YourClass.generateSaltString();
String salt3 = YourClass.generateSaltString();
String salt4 = YourClass.generateSaltString();
assertNotNull(salt1);
assertNotNull(salt2);
assertNotNull(salt3);
assertNotNull(salt4);
assertNotEqual(salt1, salt2);
assertNotEqual(salt1, salt3);
assertNotEqual(salt1, salt4);
assertNotEqual(salt2, salt3);
assertNotEqual(salt2, salt4);
assertNotEqual(salt3, salt4);
}
考虑到 GaborSch 的评论,我认为测试的实现有点模糊,因为有可能 - 尽管不太可能 - 函数的两次调用将生成相同的盐:
@Test
public void testGenerateSaltString() {
String salt1;
String salt2;
int differenceCount = 0;
for(int i = 0; i < 1000; i++ ) {
String salt1 = YourClass.generateSaltString();
String salt2 = YourClass.generateSaltString();
// null is still inacceptable
assertNotNull(salt1);
assertNotNull(salt2);
if(!salt1.equalsIgnoreCase(salt2)) {
differenceCount++;
}
}
// check if at least at 95% of all tries resultet in different strings
// change this value according to your needs
assertTrue(differenceCount >= 950);
}
我可以想到两个测试用例 -
您可以检查 3 件事:
Base64
字符串)例如,下面的代码可以工作。我生成 100 种不同的随机盐,并允许其中最多 1 次匹配。
@Test
public void testGenerateSaltString() {
Set<String> salts = new HashSet<String>();
int countSame = 0;
BASE64Decoder decoder = new BASE64Decoder();
for(int i=0; i<100; i++) {
String salt = YourClass.generateSaltString();
assertNotNull(salt);
try {
decoder.decodeBuffer(encodedBytes);
} catch (Exception e) {
fail("Not Base64");
}
if (salts.contains(salt)) {
sameCount++;
}
salts.add(salt);
}
assertTrue(countSame <= 1);
}