Created
April 14, 2015 23:44
-
-
Save bcoughlan/9940b5a349c5f872395e to your computer and use it in GitHub Desktop.
Replacing a SecureRandom.getInstance() algorithm in Java for mocking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
When writing tests, it can be a burden to make assertions about code with non-deterministic behavior such as random number generation. The above class shows a way of mocking SecureRandom.getInstance() to produce deterministic behaviour without using bytecode-modifying mocking frameworks such as PowerMock or jMockIt, which often cause headaches by interfering with code coverage tools. | |
Probably no-one besides me will ever need to do this, but after dealing with the side effects of power-mocking tools all week, I liked the solution too much to share :) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.security.NoSuchAlgorithmException; | |
import java.security.Provider; | |
import java.security.SecureRandom; | |
import java.security.SecureRandomSpi; | |
import java.security.Security; | |
public class ReplaceAlgorithms { | |
public static void main(String[] args) throws NoSuchAlgorithmException { | |
byte[] bytes = new byte[16]; | |
SecureRandom.getInstance("SHA1PRNG").nextBytes(bytes); | |
System.out.println(new String(bytes)); | |
} | |
static { | |
// Give fake provider highest priority | |
Security.insertProviderAt(new FakeSha1Provider(), 1); | |
} | |
public static class FakeSha1Provider extends Provider { | |
protected FakeSha1Provider() { | |
super("FakeSha1Provider", 1.0, null); | |
put("SecureRandom.SHA1PRNG", FakeAlgorithm.class.getName()); | |
} | |
} | |
public static class FakeAlgorithm extends SecureRandomSpi { | |
@Override | |
protected void engineSetSeed(byte[] seed) { | |
for (int i = 0; i < seed.length; i++) { | |
// Deterministic result for a given length | |
seed[i] = (byte) ('a' + (i % 26)); | |
} | |
} | |
@Override | |
protected void engineNextBytes(byte[] bytes) { | |
for (int i = 0; i < bytes.length; i++) { | |
bytes[i] = (byte) ('a' + (i % 26)); | |
} | |
} | |
@Override | |
protected byte[] engineGenerateSeed(int numBytes) { | |
byte[] bytes = new byte[numBytes]; | |
for (int i = 0; i < numBytes; i++) { | |
bytes[i] = (byte) ('a' + (i % 26)); | |
} | |
return bytes; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment