Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the default exclusion policy public #389

Closed
elexx opened this issue Feb 13, 2020 · 1 comment
Closed

Make the default exclusion policy public #389

elexx opened this issue Feb 13, 2020 · 1 comment
Milestone

Comments

@elexx
Copy link

elexx commented Feb 13, 2020

I need EasyRandom to ignore fields in superclasses.

Given the following classes (getter/setter for better readability omitted) ...

public abstract class BaseEntity {
    private long id;
    private int version;
}

public class User extends BaseEntity {
    private String name;
}

... I want EasyRandom to only fill the name when creating objects with easyRandom.nextObject(User.class).

I tried two different ways to implement this, but I'm not happy with either one of them:

// works but is not really futureproof. New superclasses must be added to the list
IGNORED_CLASSES =  Arrays.asList(BaseEntity.class);
...
    .excludeField(f -> !IGNORED_CLASSES.contains(field.getDeclaringClass()))
// works but it's a bit hacky imho.
// delegating to the original ExclusionPolicy instead of simply extending it, because
//    a) the default policy might change and
//    b) the original implementation is package-private: https://github.com/j-easy/easy-random/blob/master/easy-random-core/src/main/java/org/jeasy/random/ExclusionChecker.java
EasyRandomParameters parameters = new EasyRandomParameters();
ExclusionPolicy originalPolicy = parameters.getExclusionPolicy();
parameters.setExclusionPolicy(new ExclusionPolicy() {
    @Override
    public boolean shouldBeExcluded(Field field, RandomizerContext context) {
        return originalPolicy.shouldBeExcluded(field, context) || field.getDeclaringClass() == context.getCurrentObject().getClass();
    }

    @Override
    public boolean shouldBeExcluded(Class<?> type, RandomizerContext context) {
        return originalPolicy.shouldBeExcluded(type, context);
    }
});

Unfortunately using org.jeasy.random.annotation.Exclude is also not an option, because the superclasses actually live inside another library I have no control over.

@fmbenhassine fmbenhassine added this to the 4.2.0 milestone Mar 4, 2020
@fmbenhassine
Copy link
Member

Hi @elexx ,

Thank you for opening this issue!

delegating to the original ExclusionPolicy instead of simply extending it

I made ExclusionChecker public and renamed it to DefaultExclusionPolicy. You can now extend it with additional exclusion logic and register it in your config. Here is a quick test that shows how to exclude inherited fields based on your example:

public abstract class BaseEntity {
    protected Long id;
    protected Integer version;
}

public class User extends BaseEntity {
    private String name;
}

public class MyExclusionPolicy extends DefaultExclusionPolicy {
    @Override
    public boolean shouldBeExcluded(Field field, RandomizerContext context) {
        return super.shouldBeExcluded(field, context) || !field.getDeclaringClass().equals(context.getTargetType());
    }
}

@Test
void testInheritedFieldExclusion() {
    // given
    EasyRandomParameters parameters = new EasyRandomParameters()
            .exclusionPolicy(new MyExclusionPolicy());
    EasyRandom easyRandom = new EasyRandom(parameters);
    
    // when
    User user = easyRandom.nextObject(User.class);

    // then
    Assertions.assertThat(user.name).isNotNull();
    Assertions.assertThat(user.id).isNull();
    Assertions.assertThat(user.version).isNull();
}

This test passes with 4.2.0-SNAPSHOT and the change will be part of the upcoming 4.2 release. Feel free to give it a try and share your feedback!

@fmbenhassine fmbenhassine changed the title There is no easy way to exclude fields declared in superclasses Make the default exclusion policy public Mar 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants