Recently I've been doing major refactoring of integration tests. I've found many tests which do stuff like that:
for (int i = 0; i < 256; i++) {
addProduct(UUID.randomUUID().toString);
}
It's pretty ugly, isn't it ?
It would be nice to have a small tool that invokes given piece of code n times.
In Java 8 we can use IntStream:
IntStream.range(0, 256).forEach(i -> addProduct(UUID.randomUUID().toString()));
Looks better but it's still not very readable.
Again I've started with a test that specifies how the tool should work:
@Test
public void shouldInvokeCommandFiveTimes() throws Exception {
// given
final List<String> list = newArrayList();
// when
times(5).invoke(() -> list.add("item"));
// then
assertThat(list).containsExactly("item", "item", "item", "item", "item");
}
I've come up with the following class:
/**
* @author Grzegorz Taramina
* Created on: 12/07/16
*/
public class Times {
private final int times;
private Times(final int times) {
this.times = times;
}
public static Times times(final int times) {
Assert.isTrue(times >= 0, "times must be at least equal to zero");
return new Times(times);
}
public void invoke(final Runnable runnable) {
IntStream.range(0, times).forEach(i -> runnable.run());
}
}
It's very simple but makes code concise and readable:
times(5).invoke(() -> addProduct(randomUUID().toString));
I might have exaggerated saying that this is functional tool. It's simply higher order function but very useful.
No comments:
Post a Comment