Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I generate Mapstruct mapper implementations for test scope mapper interface in Gradle build?

I'm having a simple Java single module Gradle project in which I use Mapstruct for the Java mapping. My build.gradle looks like this:

plugins {
    id 'java-library'
    id 'groovy'
    id 'net.ltgt.apt' version '0.20'
}

repositories {
    jcenter()
}

dependencies {
    implementation 'org.mapstruct:mapstruct-jdk8:1.2.0.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'

    testImplementation 'org.codehaus.groovy:groovy-all:2.5.5'

    // Use the awesome Spock testing and specification framework even with Java
    testImplementation 'org.spockframework:spock-core:1.2-groovy-2.5'
    testImplementation 'junit:junit:4.12'
}

sourceSets {
    main {
        java {
            srcDirs "${project.buildDir}/generated/sources/annotationProcessor/java/main"
        }
    }
    test {
        java {
            srcDirs "${project.buildDir}/generated/sources/annotationProcessor/java/test"
        }
    }
}

My source folder contains the following Java source code:

src
├── main
│   ├── java
│   │   └── ch
│   │       └── silviowangler
│   │           ├── Person.java
│   │           ├── SomeMapper.java
│   │           └── User.java
│   └── resources
└── test
    ├── groovy
    │   └── ch
    │       └── silviowangler
    ├── java
    │   └── ch
    │       └── silviowangler
    │           └── YoloMapper.java
    └── resources

SomeMapper is a simple mapper interface that looks like this

@Mapper
public interface SomeMapper {

    @Mappings({
            @Mapping(target = "firstName", source = "nickname"),
            @Mapping(target = "surname", ignore = true),
            @Mapping(target = "dateOfBirth", ignore = true)
    })
    Person fromString(User user);
}

And the YoloMapper that resides in the test scope looks like that

@Mapper
public interface YoloMapper {

    String fromLocalDate(LocalDate localDate);
}

When I run ./gradlew clean cTJ the build completes successfully and the annotation processor generates a mapper implementation for SimpleMapper but it does not generate anything for the YoloMapper. The build folder after the build looks like

build
├── classes
│   └── java
│       ├── main
│       │   └── ch
│       │       └── silviowangler
│       │           ├── Person.class
│       │           ├── SomeMapper.class
│       │           ├── SomeMapperImpl.class
│       │           └── User.class
│       └── test
│           └── ch
│               └── silviowangler
│                   └── YoloMapper.class
├── generated
│   └── sources
│       └── annotationProcessor
│           └── java
│               ├── main
│               │   └── ch
│               │       └── silviowangler
│               │           └── SomeMapperImpl.java
│               └── test
└── tmp
    ├── compileJava
    └── compileTestJava

How can I make Gradle to tell the annotation processor to generate Mapstruct mapper implementation in the test scope?

like image 899
saw303 Avatar asked Jan 28 '19 11:01

saw303


People also ask

How does MapStruct generate implementation?

MapStruct is an open-source Java-based code generator which creates code for mapping implementations. It uses annotation-processing to generate mapper class implementations during compilation and greatly reduces the amount of boilerplate code which would regularly be written by hand.

How do I map a MapStruct collection?

In general, mapping collections with MapStruct works in the same way as for simple types. Basically, we have to create a simple interface or abstract class and declare the mapping methods. Based on our declarations, MapStruct will generate the mapping code automatically.

What is MapStruct AfterMapping?

Annotation Type AfterMappingMarks a method to be invoked at the end of a generated mapping method, right before the last return statement of the mapping method. The method can be implemented in an abstract mapper class, be declared in a type (class or interface) referenced in Mapper.


1 Answers

You need to configure the testAnnocationProcess configuration, as follows:

dependencies{

    // for Main sources set
    implementation 'org.mapstruct:mapstruct-jdk8:1.2.0.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.2.0.Final'

    // for Test sources set  
    testAnnotationProcessor "org.mapstruct:mapstruct-processor:1.2.0.Final"

}
like image 200
M.Ricciuti Avatar answered Oct 03 '22 02:10

M.Ricciuti