mardi 10 décembre 2019

What's the correct way to deal with tests in a modular system?

So, I decided to modularize my system and, until getting to tests, everything's been ok. But now, I really don't know the correct way to deal with the test package.

My project is structured like this:

enter image description here

Basically the thing is that the EntityDTOConverter is an utility class that converts an entity to a DTO and vice versa through reflection, using the ModelMapper library.

Now my module-info.java looks like this:

module com.vet.clinic.core.app {
  requires com.vet.clinic.core.domain;

  requires typetools;
  requires modelmapper;
  requires jakarta.el;
  requires spring.context;
  requires org.mapstruct.processor;

  exports com.vet.clinic.core.app.converter;
  exports com.vet.clinic.core.app.dto;
}

If I run as is, I get the following error:

------------------------------------------------------------------------------- Test set: com.vet.clinic.core.app.converter.EntityDTOConverterTest ------------------------------------------------------------------------------- Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.019 s <<< FAILURE! - in com.vet.clinic.core.app.converter.EntityDTOConverterTest com.vet.clinic.core.app.converter.EntityDTOConverterTest Time elapsed: 0.018 s <<< ERROR! java.lang.reflect.InaccessibleObjectException: Unable to make public static void com.vet.clinic.core.app.converter.EntityDTOConverterTest.once() accessible: module com.vet.clinic.core.app does not "opens com.vet.clinic.core.app.converter" to unnamed module @20f5239f

Now if I add the following line to the module-info.java:

opens com.vet.clinic.core.app.converter;

Then the above error is gone, but then I get:

------------------------------------------------------------------------------- Test set: com.vet.clinic.core.app.converter.EntityDTOConverterTest ------------------------------------------------------------------------------- Tests run: 4, Failures: 0, Errors: 4, Skipped: 0, Time elapsed: 0.163 s <<< FAILURE! - in com.vet.clinic.core.app.converter.EntityDTOConverterTest givenDTO_whenConvertIsCalled_thenConvertToBaseEntity Time elapsed: 0.063 s <<< ERROR! org.modelmapper.MappingException: ModelMapper mapping errors:

1) Error mapping com.vet.clinic.core.app.mock.dto.MockBaseEntityDTO to com.vet.clinic.core.app.mock.dto.MockBaseEntity

1 error at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenDTO_whenConvertIsCalled_thenConvertToBaseEntity(EntityDTOConverterTest.java:58) Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public void com.vet.clinic.core.app.mock.dto.MockBaseEntity.setName(java.lang.String) accessible: module com.vet.clinic.core.app does not "exports com.vet.clinic.core.app.mock.dto" to module modelmapper at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenDTO_whenConvertIsCalled_thenConvertToBaseEntity(EntityDTOConverterTest.java:58)

givenBaseEntity_whenConvertIsCalled_thenConvertToDTO Time elapsed: 0.003 s <<< ERROR! org.modelmapper.MappingException: ModelMapper mapping errors:

1) Error mapping com.vet.clinic.core.app.mock.dto.MockBaseEntity to com.vet.clinic.core.app.mock.dto.MockBaseEntityDTO

1 error at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenBaseEntity_whenConvertIsCalled_thenConvertToDTO(EntityDTOConverterTest.java:45) Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public void com.vet.clinic.core.app.mock.dto.MockBaseEntityDTO.setName(java.lang.String) accessible: module com.vet.clinic.core.app does not "exports com.vet.clinic.core.app.mock.dto" to module modelmapper at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenBaseEntity_whenConvertIsCalled_thenConvertToDTO(EntityDTOConverterTest.java:45)

givenListAudibleDTO_whenConvertIsCalled_thenConvertToListBaseEntity Time elapsed: 0.029 s <<< ERROR! org.modelmapper.MappingException: ModelMapper mapping errors:

1) Error mapping com.vet.clinic.core.app.mock.dto.MockAudibleBaseEntityDTO to com.vet.clinic.core.app.mock.dto.MockBaseEntity

1 error at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenListAudibleDTO_whenConvertIsCalled_thenConvertToListBaseEntity(EntityDTOConverterTest.java:88) Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public void com.vet.clinic.core.app.mock.dto.MockBaseEntity.setName(java.lang.String) accessible: module com.vet.clinic.core.app does not "exports com.vet.clinic.core.app.mock.dto" to module modelmapper at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenListAudibleDTO_whenConvertIsCalled_thenConvertToListBaseEntity(EntityDTOConverterTest.java:88)

givenListBaseEntity_whenConvertIsCalled_thenConvertToListAudibleDTO Time elapsed: 0.007 s <<< ERROR! org.modelmapper.MappingException: ModelMapper mapping errors:

1) Error mapping com.vet.clinic.core.app.mock.dto.MockBaseEntity to com.vet.clinic.core.app.mock.dto.MockAudibleBaseEntityDTO

1 error at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenListBaseEntity_whenConvertIsCalled_thenConvertToListAudibleDTO(EntityDTOConverterTest.java:72) Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make public void com.vet.clinic.core.app.mock.dto.MockBaseEntityDTO.setName(java.lang.String) accessible: module com.vet.clinic.core.app does not "exports com.vet.clinic.core.app.mock.dto" to module modelmapper at com.vet.clinic.core.app@0.1.0-SNAPSHOT/com.vet.clinic.core.app.converter.EntityDTOConverterTest.givenListBaseEntity_whenConvertIsCalled_thenConvertToListAudibleDTO(EntityDTOConverterTest.java:72)

Now I can't do the suggested fix ("exports com.vet.clinic.core.app.mock.dto" to module modelmapper), since this package is only present in the test scope and is not visible for the module-info.java.

By checking some other related questions like this, I then tried to add a module-info.java into src/test/java. Despite the fact my IDE (intelliJ ultimate) shows an error saying 'module-info.java already exists in the module', the code can be run.

By adding a module-info.java as simple as that:

module core.app.test {
  requires com.vet.clinic.core.domain;
  requires org.junit.jupiter.api;
  exports com.vet.clinic.core.app.mock.dto to modelmapper;
}

...I then start to get the following:

[ERROR] module java.persistence reads package org.codehaus.groovy.runtime from both org.codehaus.groovy.xml and org.codehaus.groovy [ERROR] module java.persistence reads package groovy.xml from both org.codehaus.groovy.xml and org.codehaus.groovy [ERROR] module java.persistence reads package groovy.util from both org.codehaus.groovy.xml and org.codehaus.groovy [ERROR] module java.persistence reads package org.codehaus.groovy.runtime from both org.codehaus.groovy.xml and org.codehaus.groovy.nio [ERROR] module java.persistence reads package org.codehaus.groovy.runtime from both org.codehaus.groovy.xml and org.codehaus.groovy.sql [ERROR] module java.persistence reads package org.json from both android.json and jsonassert [ERROR] module java.persistence reads package org.codehaus.groovy.transform from both org.codehaus.groovy and org.codehaus.groovy.test [ERROR] module java.persistence reads package org.codehaus.groovy.runtime from both org.codehaus.groovy.xml and org.codehaus.groovy.test [ERROR] module java.persistence reads package groovy.util from both org.codehaus.groovy.xml and org.codehaus.groovy.test [ERROR] module java.persistence reads package groovy.transform from both org.codehaus.groovy and org.codehaus.groovy.test [ERROR] module java.persistence reads package groovy.lang from both org.codehaus.groovy and org.codehaus.groovy.test

These 11 errors happen multiple times with different modules, not only with java.persistence.

I know this error has to do with automatic modules, but to be honest I have no clue which direction I have to go from here. Any tips?

Aucun commentaire:

Enregistrer un commentaire