Skip to content

Commit 2ae4fd5

Browse files
authored
Merge pull request #1626 from datafaker-net/tests/1623-fix-weighted-flaky-test
2 parents 03946de + c106ae5 commit 2ae4fd5

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package net.datafaker.service;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Random;
6+
7+
import static java.util.Collections.shuffle;
8+
9+
/**
10+
* Implementation of {@link java.util.random.RandomGenerator}
11+
* that guarantees an evenly distributed set of values in a random order.
12+
*
13+
* Good for using in tests instead of just {@link java.util.Random}
14+
*/
15+
public class EvenlyDistributedRandomGenerator extends Random {
16+
private final List<Double> values;
17+
private int index;
18+
19+
/**
20+
* Create a Random instance that splits [lower, upper) to N equal intervals,
21+
* picks a single value from each interval, and returns them in random order.
22+
*/
23+
public EvenlyDistributedRandomGenerator(int lowerInclusive, int upperExclusive, int count) {
24+
this.values = fillEvenly(lowerInclusive, upperExclusive, count);
25+
shuffle(values);
26+
}
27+
28+
private static List<Double> fillEvenly(int lowerInclusive, int upperExclusive, int count) {
29+
List<Double> values = new ArrayList<>(count);
30+
31+
Random random = new Random();
32+
double step = 1.0d * (upperExclusive - lowerInclusive) / count;
33+
for (int i = 0; i < count; i++) {
34+
values.add(lowerInclusive + i * step + random.nextDouble(step));
35+
}
36+
return values;
37+
}
38+
39+
@Override
40+
public double nextDouble() {
41+
return values.get(index++);
42+
}
43+
44+
@Override
45+
public int nextInt(int bound) {
46+
return (int) values.get(index++).doubleValue();
47+
}
48+
}

src/test/java/net/datafaker/service/WeightedRandomSelectorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,13 +115,13 @@ void testWeightedArrayElementWithSingleElement(WeightedRandomSelector selector)
115115
@ParameterizedTest
116116
@MethodSource("multipleElementsProvider")
117117
void testWeightedArrayElementWithMultipleElements(List<Map<String, Object>> items, Map<String, Integer> expectedCounts) {
118-
WeightedRandomSelector selector = new WeightedRandomSelector(new Random());
118+
WeightedRandomSelector selector = new WeightedRandomSelector(new EvenlyDistributedRandomGenerator(0, 1, ITERATIONS));
119119

120120
Map<String, Integer> counts = countResults(selector, items);
121121

122122
assertThat(counts.keySet()).containsExactlyInAnyOrderElementsOf(expectedCounts.keySet());
123123
for (String element : expectedCounts.keySet()) {
124-
assertThat(counts.get(element)).isCloseTo(expectedCounts.get(element), withinPercentage(20));
124+
assertThat(counts.get(element)).isCloseTo(expectedCounts.get(element), withinPercentage(1));
125125
}
126126
}
127127

0 commit comments

Comments
 (0)