javajunit5instancio

Can Instancio generate data for interfaces and abstract classes?


I used to use Easy-Random to generate JUnit5 test data. However, as it does not seem to be developed anymore, doesn't support Java records, and in general seems to be less flexible than Instancio, I've decided to migrate. Instancio, out of the box, provides a lot of nice features, enabling quicker testing (easier parametrized tests, taking into consideration Javax, etc.). However, there is one drawback.

The objects returned by our persistence layer are auto-generated implementations of some record interface which look like:

interface SomeRecord {
  getUid();
}

Easy-Random was able to find the implementation and generate a random record.

I cannot find any information on how to resolve this or a workaround in Instancio's docs or anywhere else. Has anyone been able to do something similar?


Solution

  • For a one-off case, the easiest option is to specify the implementation manually, e.g.

    Person person = Instancio.of(Person.class)
        .subtype(all(Pet.class), Cat.class)
        .create();
    

    However, I assume that you want implementations to be found automatically. If so, there are a couple of options.

    1. Implement the TypeResolver (see InstancioServiceProvider documentation):
    class MyTypeResolver implements TypeResolver {
        private Map<Class<?>, Class<?>> subtypeMap = new HashMap<>();
    
        @Override
        public Class<?> getSubtype(Class<?> type) {
            return subtypeMap.get(type);
        }
    }
    

    The mapping can be specified manually, or automated by scanning the classpath using a library, such as ClassGraph.

    See this GitHub repo for a sample implementation

    1. Another approach is to map types via Settings. This can also be specified manually, or automated, for example: https://github.com/dafriedmann/instancio-jandex-subtype-mapping