public static String generateSaltString() {
SecureRandom random = new SecureRandom();
byte[] salt = random.generateSeed(12);
return byteToBase64(salt);
}
Wondering how to write test case using Junit for this method. Any suggestion?
public static String generateSaltString() {
SecureRandom random = new SecureRandom();
byte[] salt = random.generateSeed(12);
return byteToBase64(salt);
}
Wondering how to write test case using Junit for this method. Any suggestion?
First thing is that new SecureRandom() can be potentially very slow so you might want to cache it. Look at this answer and this one too.
I would refactor your code as follows
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 looks like a utility method call so it can go into a class RandomUtil which looks like this
class RandomUtil {
private SecureRandom random = new SecureRandom();
public byte[] generateSeed(int seed) {
return random.generateSeed(seed);
}
}
Now your test class for DoRandomStuff would be easy to write. Inject a mocked randomUtil using some testing framework like Mockito. Make the mockedRandomUtil.generateSeed(int) method return a fixed number. Your test is really for checking whether byteToBase64() method is doing what its supposed to do. Now you have a deterministic number for your test case. You can give all kinds of numbers which can be generated by SecureRandom in your test class as separate test cases to check byteToBase64() result. As a plus your random number generation code is now decoupled from your base64 code.
Hope it helped.
i would test if the result is not null and then call the method several times and compare the results to show that each call returns a different value.
But remember: This says nothing about the quality of the randomness of your results!
@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);
}
Considering GaborSch's comments i thought of a somewhat fuzzy implementation of the test since it is possible - though unlikely - that two calls of the function will generate the same salt:
@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);
}
I can think of two test cases -
You can check 3 things:
Base64
String)For example, the following code could work. I generate 100 different random salts, and allow maximum 1 match among them.
@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);
}