Skip to content

Commit

Permalink
implement issue #28 : add support to use java 8 Suppliers as Randomizers
Browse files Browse the repository at this point in the history
  • Loading branch information
fmbenhassine committed Apr 3, 2016
1 parent 63b0398 commit b248b1e
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
import io.github.benas.randombeans.randomizers.registry.CustomRandomizerRegistry;

import java.util.*;
import java.util.function.Supplier;

import static io.github.benas.randombeans.RandomizerProxy.asRandomizer;
import static io.github.benas.randombeans.util.Constants.DEFAULT_SEED;

/**
Expand Down Expand Up @@ -77,6 +79,18 @@ public <T, F, R> EnhancedRandomBuilder randomize(FieldDefinition<T, F> fieldDefi
return this;
}

/**
* Register a supplier as randomizer for a given field.
*
* @param fieldDefinition definition of the field to randomize
* @param supplier the custom {@link Supplier} to use
* @return a pre configured {@link EnhancedRandomBuilder} instance
*/
public <T, F, R> EnhancedRandomBuilder randomize(FieldDefinition<T, F> fieldDefinition, Supplier<R> supplier) {
customRandomizerRegistry.registerRandomizer(fieldDefinition.getName(), fieldDefinition.getType(), fieldDefinition.getClazz(), asRandomizer(supplier));
return this;
}

/**
* Register a custom randomizer for a given type.
*
Expand All @@ -89,6 +103,18 @@ public <T, R> EnhancedRandomBuilder randomize(Class<T> type, Randomizer<R> rando
return this;
}

/**
* Register a supplier as randomizer for a given type.
*
* @param type class of the type to randomize
* @param supplier the custom {@link Supplier} to use
* @return a pre configured {@link EnhancedRandomBuilder} instance
*/
public <T, R> EnhancedRandomBuilder randomize(Class<T> type, Supplier<R> supplier) {
customRandomizerRegistry.registerRandomizer(type, asRandomizer(supplier));
return this;
}

/**
* Exclude a field from being populated.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.github.benas.randombeans;

import io.github.benas.randombeans.api.Randomizer;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.function.Supplier;

/**
* Dynamic proxy that adapts a {@link java.util.function.Supplier} to a {@link Randomizer}.
*
* @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
*/
class RandomizerProxy implements InvocationHandler {

private Supplier<?> target;

RandomizerProxy(final Supplier<?> target) {
this.target = target;
}

/**
* Create a dynamic proxy that adapts the given {@link Supplier} to a {@link Randomizer}.
* @param supplier to adapt
* @return the proxy randomizer
*/
static Randomizer<?> asRandomizer(final Supplier<?> supplier) {
return (Randomizer<?>) Proxy.newProxyInstance(
Randomizer.class.getClassLoader(),
new Class[]{Randomizer.class},
new RandomizerProxy(supplier));
}

@Override
public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
if ("getRandomValue".equals(method.getName())) {
return target.getClass().getMethod("get").invoke(target, args);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import io.github.benas.randombeans.beans.*;
import io.github.benas.randombeans.randomizers.misc.ConstantRandomizer;

import org.assertj.core.api.Assertions;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
Expand All @@ -38,6 +39,7 @@

import java.util.Date;
import java.util.List;
import java.util.function.Supplier;

import static io.github.benas.randombeans.EnhancedRandomBuilder.aNewEnhancedRandomBuilder;
import static io.github.benas.randombeans.FieldDefinitionBuilder.field;
Expand All @@ -49,18 +51,22 @@
@RunWith(MockitoJUnitRunner.class)
public class EnhancedRandomImplTest {

private static final String NAME = "foo";
private static final String FOO = "foo";
private static final long SEED = 123L;

@Mock
private Randomizer<String> randomizer;

@Mock
private Supplier<String> supplier;

private EnhancedRandom enhancedRandom;

@Before
public void setUp() {
enhancedRandom = aNewEnhancedRandomBuilder().build();
when(randomizer.getRandomValue()).thenReturn(NAME);
when(randomizer.getRandomValue()).thenReturn(FOO);
when(supplier.get()).thenReturn(FOO);
}

@Test
Expand Down Expand Up @@ -131,7 +137,7 @@ public void generatedBeansWithCustomRandomizersShouldBeCorrectlyPopulated() {
Person person = enhancedRandom.nextObject(Person.class);

assertThat(person).isNotNull();
assertThat(person.getName()).isEqualTo(NAME);
assertThat(person.getName()).isEqualTo(FOO);
}

@Test
Expand Down Expand Up @@ -255,6 +261,23 @@ public void generatedObjectShouldBeAlwaysTheSameForTheSameSeed() {
assertThat(actualInts).isEqualTo(expectedInts);
}

@Test
public void supplierShouldBehaveLikeRandomizer() throws Exception {
// Given
enhancedRandom = aNewEnhancedRandomBuilder().randomize(String.class, supplier).build(); // All string fields should be equal to FOO

// When
Person actual = enhancedRandom.nextObject(Person.class);

// Then
assertThat(actual).isNotNull();
assertThat(actual.getPhoneNumber()).isEqualTo(FOO);
assertThat(actual.getName()).isEqualTo(FOO);
assertThat(actual.getEmail()).isEqualTo(FOO);
assertThat(actual.getEmail()).isEqualTo(FOO);
assertThat(actual.getExcluded()).isNull();
}


private Person buildExpectedPerson() {
Person expectedPerson = new Person();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package io.github.benas.randombeans;

import io.github.benas.randombeans.api.Randomizer;
import org.junit.Test;

import java.util.function.Supplier;

import static org.assertj.core.api.Assertions.assertThat;

public class RandomizerProxyTest {

public static final String FOO = "foo";

@Test
public void theRandomizerProxyShouldBehaveLikeTheSupplier() throws Exception {
// Given
MySupplier supplier = new MySupplier();

// When
Randomizer<?> randomizer = RandomizerProxy.asRandomizer(supplier);

// Then
assertThat(randomizer.getRandomValue()).isInstanceOf(String.class).isEqualTo(FOO);
}

class MySupplier implements Supplier<String> {

@Override
public String get() {
return FOO;
}

}
}

0 comments on commit b248b1e

Please sign in to comment.