Reputation: 13
I have a program that is generating pseudo random numbers(Only lowercase, uppercase and digits are allowed).
/**
*
* @return - returns a random digit (from 0 to 9)
*
*/
int randomDigits() {
return (int) (Math.random() * 10);
}
/**
*
* @return - returns a random lowercase (from "a" to "z")
*/
char randomLowerCase() {
return (char) ('a' + Math.random() * 26);
}
/**
*
* @return - returns a random uppercase (from "A" to "Z")
*/
char randomUpperCase() {
return (char) ('A' + Math.random() * 26);
}
/**
*
* @return - returns a random number between 1 and 3.
*
*/
char randomChoice() {
return (char) ((char) (Math.random() * 3) + 1);
}
/**
*
* @param length
* - the length of the random string.
* @return - returns a combined random string. All elements are builder side
* by side.
*
* We use the randomChoice method to get randomly upper, lower and
* digits.
*/
public String stringBuilder(int length) {
StringBuilder result = new StringBuilder();
int len = length;
for (int i = 0; i < len; i++) {
int ch = randomChoice();
if (ch == 1) {
result.append(randomDigits());
}
if (ch == 2) {
result.append(randomLowerCase());
}
if (ch == 3) {
result.append(randomUpperCase());
}
}
return result.toString();
}
How can i make a test for that code. I try to test the range for the digits (form 0 to 9)
int minRange = 0;
int maxRange = 0;
for (int i = 0; i < 100000; i++) {
int result = item.randomDigits();
if (result == 52) {
minRange++;
} else {
if (result == 19) {
maxRange++;
}
}
}
LOGGER.info("The min range in the digit is 0, and in the test appeared: {}", minRange);
LOGGER.info("The max range in the digit is 9, and in the test appeared: {}", maxRange);
But i cant find how to test the lower or upper?
Upvotes: 1
Views: 6160
Reputation: 27976
Testing code which uses any randomness is tricky. There are two approaches you can take:
This might look something like:
for (int i = 0; i < 1000000; i++)
assertTrue(isValid(new RandomVal()));
If you want to check that all your characters appear at least once:
assertEquals(26 * 2 + 9, IntStream.range(0, 1000000)
.mapToObj(n -> stringBuilder(6))
.flatMap(String::chars)
.collect(Collectors.toSet())
.size());
This uses Java 8 and essentially adds every character (as an integer) to the set and then checks how large it is afterwards.
This might look something like:
Random mockRandom = mock(Random.class);
when(mockRandom.nextFloat()).thenReturn(0.0f);
assertTrue(isValid(new RandomVal(mockRandom));
when(mockRandom.nextFloat()).thenReturn(1.0f - Float.MIN_VALUE);
assertTrue(isValid(new RandomVal(mockRandom));
For completeness it's worth doing both of these.
Upvotes: 2
Reputation: 392
If I understand your problem resolution is simple
int minRange = 999999; //improbable big value
int maxRange = -999999; //improbable low value
for (int i = 0; i < 100000; i++) {
int result = item.randomDigits();
minRange = Math.min(result, minRange);
maxRange = Math.max(result, maxRange);
}
Please try it. If you don't like Math library you can of course do it without it
for (int i = 0; i < 100000; i++) {
int result = item.randomDigits();
if (result < minRange) {
minRange = result;
}
if (result > maxRange) {
maxRange = result;
}
}
Upvotes: -1