JavaRush /Blog Jawa /Random-JV /Apa Mapstruct lan carane ngatur kanthi bener kanggo testi...

Apa Mapstruct lan carane ngatur kanthi bener kanggo testing unit ing aplikasi SpringBoot

Diterbitake ing grup

Latar mburi

Halo kabeh, kanca lan pembaca sing daktresnani! Sadurunge kita nulis artikel, latar mburi sethitik ... Aku bubar ketemu masalah nggarap perpustakaan Mapstruct , kang sedhela diterangake ing saluran telegram kene . Ing komentar, masalah karo kiriman wis ditanggulangi; kancaku saka proyek sadurunge mbantu iki. Apa Mapstruct lan carane ngatur kanthi bener kanggo testing unit ing aplikasi SpringBoot.  Bagean 1 - 1Sawise iku, aku mutusake kanggo nulis artikel babagan topik iki, nanging mesthine kita ora bakal njupuk tampilan sing sempit lan bakal nyoba nyepetake, ngerti apa Mapstruct lan apa sing dibutuhake, lan nggunakake conto nyata kita bakal. nganalisa kahanan sing kedadeyan sadurunge lan cara ngatasi. Mulane, aku banget nyaranake nindakake kabeh petungan ing podo karo maca artikel supaya bisa nemu kabeh ing laku. Sadurunge miwiti, langganan saluran telegramku , aku ngumpulake kegiatan ing kana, nulis pikirane babagan pembangunan ing Jawa lan IT umume. Langganan? apik tenan! Saiki ayo padha lunga!

Mapstruct, faq?

A generator kode kanggo cepet jinis-aman kacang mappings. Tugas pisanan kita yaiku ngerteni apa Mapstruct lan kenapa kita butuh. Umumé, sampeyan bisa maca babagan iki ing situs web resmi. Ing kaca utama situs ana telung jawaban kanggo pitakonan: apa iku? Kanggo apa? kepriye? Kita uga bakal nyoba nindakake iki:

Opo iki?

Mapstruct punika perpustakaan sing mbantu kanggo map (peta, ing umum, sing padha tansah ngomong: map, map, etc.) obyek saka sawetara entitas menyang obyek saka entitas liyane nggunakake kode kui adhedhasar konfigurasi sing diterangake liwat antarmuka.

Kanggo apa?

Umume, kita ngembangake aplikasi multi-lapisan (lapisan kanggo nggarap database, lapisan logika bisnis, lapisan kanggo interaksi aplikasi karo donya njaba) lan saben lapisan nduweni obyek dhewe kanggo nyimpen lan ngolah data. . Lan data iki kudu ditransfer saka lapisan menyang lapisan kanthi mindhah saka siji entitas menyang liyane. Kanggo sing durung nate nggarap pendekatan iki, iki bisa uga katon rumit. Contone, kita duwe entitas kanggo database Siswa. Nalika data entitas iki menyang lapisan logika bisnis (layanan), kita kudu nransfer data saka kelas Student menyang kelas StudentModel. Sabanjure, sawise kabeh manipulasi karo logika bisnis, data kudu dirilis ing njaba. Lan iki kita duwe kelas StudentDto. Mesthi wae, kita kudu ngirim data saka kelas StudentModel menyang StudentDto. Nulis kanthi tangan saben-saben cara sing bakal dipindhah iku mbutuhake tenaga kerja. Plus iki kode ekstra ing basis kode sing kudu maintained. Sampeyan bisa nggawe kesalahan. Lan Mapstruct ngasilake metode kasebut ing tahap kompilasi lan nyimpen ing sumber sing digawe.

kepriye?

Nggunakake anotasi. Kita mung kudu nggawe anotasi sing nduweni anotasi Mapper utama sing ngandhani perpustakaan yen metode ing antarmuka iki bisa digunakake kanggo nerjemahake saka siji obyek menyang liyane. Kaya sing dakkandhakake sadurunge babagan siswa, ing kasus kita iki bakal dadi antarmuka StudentMapper, sing bakal duwe sawetara cara kanggo mindhah data saka siji lapisan menyang lapisan liyane:
public class Student {
   private Long id;
   private String firstName;
   private String lastName;
   private Integer age;
}

public class StudentDTO {
   private Long id;
   private String firstName;
   private String lastName;
   private Integer age;
}

public class StudentModel {
   private Long id;
   private String firstName;
   private String lastName;
   private Integer age;
}
Kanggo kelas kasebut, kita nggawe mapper (sawise iki bakal diarani antarmuka, sing nggambarake apa sing arep kita transfer lan ing ngendi):
@Mapper
public interface StudentMapper {
   StudentModel toModel(StudentDTO dto);
   Student toEntity(StudentModel model);
   StudentModel toModel(Student entity);
   StudentDTO toDto(StudentModel model);
}
Kaendahan pendekatan iki yaiku yen jeneng lan jinis lapangan padha ing macem-macem kelas (kaya ing kasus kita), banjur setelan kanggo Mapstruct cukup kanggo ngasilake implementasine sing dibutuhake adhedhasar antarmuka StudentMapper ing tahap kompilasi, sing bakal nerjemahake. Dadi wis dadi luwih cetha, ta? Ayo luwih maju lan gunakake conto nyata kanggo nganalisa karya ing aplikasi Spring Boot.

Conto Spring Boot lan Mapstruct digunakake

Wangsulan: Bab ingkang pisanan kita kudu nggawe proyek Spring Boot lan nambah Mapstruct menyang. Kanggo perkara iki, aku duwe organisasi ing GitHub kanthi template kanggo repositori lan wiwitan kanggo Spring Boot minangka salah sawijining. Adhedhasar kasebut, kita nggawe proyek anyar: Apa Mapstruct lan carane ngatur kanthi bener kanggo testing unit ing aplikasi SpringBoot.  Bagean 1 - 2Sabanjure, kita entuk proyek kasebut . Ya, kanca-kanca, menehi bintang proyek yen sampeyan nemokake migunani, supaya aku ngerti yen aku ora nindakake iki kanthi sia-sia. Ing proyek iki, kita bakal mbukak kahanan sing daktampa nalika kerja lan diterangake ing kiriman ing saluran Telegramku . Aku bakal njelaske nganggo bentuk garis sedhela kahanan kanggo wong-wong sing ora ngerti: nalika kita nulis tes kanggo mappers (yaiku, kanggo implementasine antarmuka sing kita ngomong bab sadurungé), kita pengin tes kanggo pass cepet sabisa. Pilihan sing paling gampang karo mappers yaiku nggunakake anotasi SpringBootTest nalika nglakokake tes, sing bakal njupuk kabeh ApplicationContext saka aplikasi Spring Boot lan nyuntikake mapper sing dibutuhake kanggo tes ing tes kasebut. Nanging pilihan iki intensif sumber daya lan mbutuhake wektu luwih akeh, mula ora cocog kanggo kita. Kita kudu nulis tes unit sing mung nggawe pemetaan sing dikarepake lan mriksa manawa cara kasebut bisa digunakake kaya sing dikarepake. Napa sampeyan butuh tes supaya bisa mlaku luwih cepet? Yen tes njupuk wektu dawa, iku slows mudhun kabeh proses pembangunan. Nganti tes ngliwati kode anyar, kode iki ora bisa dianggep bener lan ora bakal dites, tegese ora bakal digawa menyang produksi lan tegese pangembang durung ngrampungake karya kasebut. Iku bakal koyone, kok nulis test kanggo perpustakaan kang operasi ora mangu? Nanging kita kudu nulis tes, amarga kita nyoba kanthi bener nggambarake mapper lan apa sing dikarepake. Kaping pisanan, kanggo nggawe karya kita luwih gampang, ayo nambah Lombok menyang proyek kita kanthi nambahake ketergantungan liyane menyang pom.xml:
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <scope>provided</scope>
</dependency>
Ing proyek kita, kita kudu pindhah saka kelas model (sing digunakake kanggo nggarap logika bisnis) menyang kelas DTO, sing digunakake kanggo komunikasi karo donya njaba. Ing versi sing disederhanakake, kita bakal nganggep yen kolom ora owah lan pemetaan kita bakal gampang. Nanging, yen ana kepinginan, sampeyan bisa nulis artikel sing luwih rinci babagan cara nggarap Mapstruct, carane ngatur, lan carane njupuk kauntungan saka keuntungan. Nanging banjur, amarga artikel iki bakal cukup dawa. Upamane ana mahasiswa sing daftar kuliah lan dosen sing dirawuhi. Ayo nggawe paket model . Adhedhasar iki, kita bakal nggawe model prasaja:
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

import java.util.List;

@Data
public class StudentDTO {

   private Long id;

   private String name;

   private List<LectureDTO> lectures;

   private List<LecturerDTO> lecturers;
}
ceramahipun
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LectureDTO {

   private Long id;

   private String name;
}
lan dosen
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LecturerDTO {

   private Long id;

   private String name;
}
Lan gawe paket dto ing jejere paket model :
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

import java.util.List;

@Data
public class StudentDTO {

   private Long id;

   private String name;

   private List<LectureDTO> lectures;

   private List<LecturerDTO> lecturers;
}
ceramah
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LectureDTO {

   private Long id;

   private String name;
}
lan dosen
package com.github.romankh3.templaterepository.springboot.dto;

import lombok.Data;

@Data
public class LecturerDTO {

   private Long id;

   private String name;
}
Saiki ayo gawe mapper sing bakal nerjemahake koleksi model ceramah dadi kumpulan ceramah DTO. Babagan pisanan sing kudu ditindakake yaiku nambah Mapstruct menyang proyek kasebut. Kanggo nindakake iki, kita bakal nggunakake situs web resmi , kabeh wis diterangake ana. Yaiku, kita kudu nambahake siji dependensi lan plugin ing memori kita (yen sampeyan duwe pitakon babagan apa memori, kene, Artikel1 lan Artikel2 ):
<dependency>
   <groupId>org.mapstruct</groupId>
   <artifactId>mapstruct</artifactId>
   <version>1.4.2.Final</version>
</dependency>
lan ing memori ing blok <build/>. sing durung ana:
<build>
   <plugins>
       <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.5.1</version>
           <configuration>
               <source>1.8</source>
               <target>1.8</target>
               <annotationProcessorPaths>
                   <path>
                       <groupId>org.mapstruct</groupId>
                       <artifactId>mapstruct-processor</artifactId>
                       <version>1.4.2.Final</version>
                   </path>
               </annotationProcessorPaths>
           </configuration>
       </plugin>
   </plugins>
</build>
Sabanjure, ayo nggawe paket mapper ing jejere dto lan model . Adhedhasar kelas sing dituduhake sadurunge, sampeyan kudu nggawe limang peta liyane:
  • Mapper LectureModel <-> LectureDTO
  • Mapper List<LectureModel> <-> List<LectureDTO>
  • Mapper LecturerModel <-> LecturerDTO
  • Daftar Mapper<LecturerModel> <-> List<LecturerDTO>
  • Mapper StudentModel <-> StudentDTO
Tindak:

LectureMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.dto.LecturerDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface LectureMapper {
   LectureDTO toDTO(LectureModel model);

   LectureModel toModel(LecturerDTO dto);
}

LectureListMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.mapstruct.Mapper;

import java.util.List;

@Mapper(componentModel = "spring", uses = LectureMapper.class)
public interface LectureListMapper {
   List<LectureModel> toModelList(List<LectureDTO> dtos);
   List<LectureDTO> toDTOList(List<LectureModel> models);
}

DosenMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring")
public interface LectureMapper {
   LectureDTO toDTO(LectureModel model);

   LectureModel toModel(LectureDTO dto);
}

LecturerListMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LecturerDTO;
import com.github.romankh3.templaterepository.springboot.model.LecturerModel;
import org.mapstruct.Mapper;

import java.util.List;

@Mapper(componentModel = "spring", uses = LecturerMapper.class)
public interface LecturerListMapper {
   List<LecturerModel> toModelList(List<LecturerDTO> dloList);
   List<LecturerDTO> toDTOList(List<LecturerModel> modelList);
}

StudentMapper

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.StudentDTO;
import com.github.romankh3.templaterepository.springboot.model.StudentModel;
import org.mapstruct.Mapper;

@Mapper(componentModel = "spring", uses = {LectureListMapper.class, LecturerListMapper.class})
public interface StudentMapper {
   StudentDTO toDTO(StudentModel model);
   StudentModel toModel(StudentDTO dto);
}
Perlu dicathet kanthi kapisah yen ing mappers kita ngrujuk menyang mappers liyane. Iki ditindakake liwat kolom panggunaan ing anotasi Mapper, kaya sing ditindakake ing StudentMapper:
@Mapper(componentModel = "spring", uses = {LectureListMapper.class, LecturerListMapper.class})
Ing kene kita nggunakake rong mapper kanggo ngepetake dhaptar kuliah lan dhaptar dosen kanthi bener. Saiki kita kudu ngumpulake kode kita lan ndeleng apa ana lan carane. Iki bisa ditindakake kanthi nggunakake perintah mvn clean compile . Nanging, ternyata, nalika nggawe implementasi Mapstruct saka mappers kita, implementasi mapper ora nimpa kolom kasebut. Kenging punapa? Pranyata ora bisa njupuk anotasi Data saka Lombok. Lan ana sing kudu ditindakake ... Mulane, kita duwe bagean anyar ing artikel kasebut.

Linking Lombok lan Mapstruct

Sawise sawetara menit nggoleki, ternyata kita kudu nyambungake Lombok lan Mapstruct kanthi cara tartamtu. Ana informasi babagan iki ing dokumentasi Mapstruct . Sawise mriksa conto sing diusulake dening pangembang saka Mapstruct, ayo nganyari pom.xml: Ayo nambah versi sing kapisah:
​​<properties>
   <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
   <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>
Ayo nambah ketergantungan sing ilang:
<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok-mapstruct-binding</artifactId>
   <version>${lombok-mapstruct-binding.version}</version>
</dependency>
Lan ayo nganyari plugin kompiler supaya bisa nyambungake Lombok lan Mapstruct:
<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-compiler-plugin</artifactId>
   <version>3.5.1</version>
   <configuration>
       <source>1.8</source>
       <target>1.8</target>
       <annotationProcessorPaths>
           <path>
               <groupId>org.mapstruct</groupId>
               <artifactId>mapstruct-processor</artifactId>
               <version>${org.mapstruct.version}</version>
           </path>
           <path>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok</artifactId>
               <version>${lombok.version}</version>
           </path>
           <path>
               <groupId>org.projectlombok</groupId>
               <artifactId>lombok-mapstruct-binding</artifactId>
               <version>${lombok-mapstruct-binding.version}</version>
           </path>
       </annotationProcessorPaths>
   </configuration>
</plugin>
Sawise kabeh iki kudu rampung. Ayo ngumpulake proyek maneh. Nanging ing ngendi sampeyan bisa nemokake kelas sing digawe Mapstruct? Dheweke ana ing sumber-sumber: ${projectDir}/target/generated-sources/annotations/ Apa Mapstruct lan carane ngatur kanthi bener kanggo testing unit ing aplikasi SpringBoot.  Bagean 1 - 3 Saiki kita wis siyap ngerteni kuciwane saka kiriman Mapstruct, ayo nyoba nggawe tes kanggo mappers.

Kita nulis tes kanggo mappers kita

Aku bakal nggawe tes cepet lan prasaja sing bakal nyoba salah siji saka mappers ing kasus ngendi kita nggawe tes integrasi lan aja kuwatir bab wektu completion sawijining:

LectureMapperTest

package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class LectureMapperTest {

   @Autowired
   private LectureMapper mapperUnderTest;

   @Test
   void shouldProperlyMapModelToDto() {
       //given
       LectureModel model = new LectureModel();
       model.setId(11L);
       model.setName("lecture name");

       //when
       LectureDTO dto = mapperUnderTest.toDTO(model);

       //then
       Assertions.assertNotNull(dto);
       Assertions.assertEquals(model.getId(), dto.getId());
       Assertions.assertEquals(model.getName(), dto.getName());
   }

   @Test
   void shouldProperlyMapDtoToModel() {
       //given
       LectureDTO dto = new LectureDTO();
       dto.setId(11L);
       dto.setName("lecture name");

       //when
       LectureModel model = mapperUnderTest.toModel(dto);

       //then
       Assertions.assertNotNull(model);
       Assertions.assertEquals(dto.getId(), model.getId());
       Assertions.assertEquals(dto.getName(), model.getName());
   }
}
Ing kene, nggunakake anotasi SpringBootTest, kita miwiti kabeh aplikasiContext lan saka iku, nggunakake anotasi Autowired, kita extract kelas sing perlu kanggo testing. Saka sudut pandang kacepetan lan gampang nulis tes, iki apik banget. Tes kasebut sukses, kabeh apik. Nanging kita bakal pindhah cara liya lan nulis tes unit kanggo mapper, contone, LectureListMapper ...
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.List;

class LectureListMapperTest {

   private final LectureListMapper lectureListMapper = new LectureListMapperImpl();

   @Test
   void shouldProperlyMapListDtosToListModels() {
       //given
       LectureDTO dto = new LectureDTO();
       dto.setId(12L);
       dto.setName("I'm BATMAN!");

       List<LectureDTO> dtos = Collections.singletonList(dto);

       //when
       List<LectureModel> models = lectureListMapper.toModelList(dtos);

       //then
       Assertions.assertNotNull(models);
       Assertions.assertEquals(1, models.size());
       Assertions.assertEquals(dto.getId(), models.get(0).getId());
       Assertions.assertEquals(dto.getName(), models.get(0).getName());
   }
}
Wiwit implementasine sing digawe Mapstruct ana ing kelas sing padha karo proyek kita, kita bisa nggunakake kanthi gampang ing tes. Kabeh katon apik - ora ana anotasi, kita nggawe kelas sing kita butuhake kanthi cara sing paling gampang. Nanging nalika kita mbukak test, kita bakal ngerti yen bakal nabrak lan bakal ana NullPointerException ing console ... Iki amarga implementasine LectureListMapper mapper katon kaya:
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Generated(
   value = "org.mapstruct.ap.MappingProcessor",
   date = "2021-12-09T21:46:12+0300",
   comments = "version: 1.4.2.Final, compiler: javac, environment: Java 15.0.2 (N/A)"
)
@Component
public class LectureListMapperImpl implements LectureListMapper {

   @Autowired
   private LectureMapper lectureMapper;

   @Override
   public List<LectureModel> toModelList(List<LectureDTO> dtos) {
       if ( dtos == null ) {
           return null;
       }

       List<LectureModel> list = new ArrayList<LectureModel>( dtos.size() );
       for ( LectureDTO lectureDTO : dtos ) {
           list.add( lectureMapper.toModel( lectureDTO ) );
       }

       return list;
   }

   @Override
   public List<LectureDTO> toDTOList(List<LectureModel> models) {
       if ( models == null ) {
           return null;
       }

       List<LectureDTO> list = new ArrayList<LectureDTO>( models.size() );
       for ( LectureModel lectureModel : models ) {
           list.add( lectureMapper.toDTO( lectureModel ) );
       }

       return list;
   }
}
Yen kita ndeleng NPE (singkatan saka NullPointerException), kita entuk saka variabel lectureMapper , sing ora diinisialisasi. Nanging ing implementasine, kita ora duwe konstruktor sing bisa miwiti variabel kasebut. Iki pancen sebabe Mapstruct ngetrapake mapper kanthi cara iki! Ing Spring, sampeyan bisa nambah kacang buncis kanggo kelas ing sawetara cara, sampeyan bisa inject mau liwat lapangan bebarengan karo Autowired anotasi, minangka rampung ndhuwur, utawa sampeyan bisa inject liwat konstruktor. Aku nemokake dhewe ing kahanan masalah ing karya nalika aku kudu ngoptimalake wektu eksekusi test. Aku mikir yen ora ana sing bisa ditindakake lan mbuwang rasa lara ing saluran Telegramku. Banjur padha nulungi aku ing komentar lan ujar manawa bisa ngatur strategi injeksi. Antarmuka Mapper duwe lapangan injectionStrategy , sing mung nampa jeneng InjectionStrategy , sing nduweni rong nilai: FIELD lan CONSTRUCTOR . Saiki, ngerti iki, ayo nambah setelan iki menyang mappers kita; Aku bakal nuduhake nggunakake LectureListMapper minangka conto :
@Mapper(componentModel = "spring", uses = LectureMapper.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface LectureListMapper {
   List<LectureModel> toModelList(List<LectureDTO> dtos);
   List<LectureDTO> toDTOList(List<LectureModel> models);
}
Aku nyorot kanthi kandel bagean sing ditambahake. Ayo ditambahake opsi iki kanggo kabeh liyane lan ngumpulake maneh proyek kasebut supaya pemetaan digawe karo baris anyar. Sawise rampung, ayo ndeleng kepiye implementasine mapper kanggo LectureListMapper wis diganti (disorot kanthi kandel bagean sing dibutuhake):
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Generated;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Generated(
   value = "org.mapstruct.ap.MappingProcessor",
   date = "2021-12-09T22:25:37+0300",
   comments = "version: 1.4.2.Final, compiler: javac, environment: Java 15.0.2 (N/A)"
)
@Component
public class LectureListMapperImpl implements LectureListMapper {

   private final LectureMapper lectureMapper;

   @Autowired
   public LectureListMapperImpl(LectureMapper lectureMapper) {

       this.lectureMapper = lectureMapper;
   }

   @Override
   public List<LectureModel> toModelList(List<LectureDTO> dtos) {
       if ( dtos == null ) {
           return null;
       }

       List<LectureModel> list = new ArrayList<LectureModel>( dtos.size() );
       for ( LectureDTO lectureDTO : dtos ) {
           list.add( lectureMapper.toModel( lectureDTO ) );
       }

       return list;
   }

   @Override
   public List<LectureDTO> toDTOList(List<LectureModel> models) {
       if ( models == null ) {
           return null;
       }

       List<LectureDTO> list = new ArrayList<LectureDTO>( models.size() );
       for ( LectureModel lectureModel : models ) {
           list.add( lectureMapper.toDTO( lectureModel ) );
       }

       return list;
   }
}
Lan saiki Mapstruct wis ngleksanakake injeksi mapper liwat konstruktor. Iki persis apa kita nyoba kanggo entuk. Saiki tes kita bakal mandheg kompilasi, ayo nganyari lan entuk:
package com.github.romankh3.templaterepository.springboot.mapper;

import com.github.romankh3.templaterepository.springboot.dto.LectureDTO;
import com.github.romankh3.templaterepository.springboot.model.LectureModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Collections;
import java.util.List;

class LectureListMapperTest {

   private final LectureListMapper lectureListMapper = new LectureListMapperImpl(new LectureMapperImpl());

   @Test
   void shouldProperlyMapListDtosToListModels() {
       //given
       LectureDTO dto = new LectureDTO();
       dto.setId(12L);
       dto.setName("I'm BATMAN!");

       List<LectureDTO> dtos = Collections.singletonList(dto);

       //when
       List<LectureModel> models = lectureListMapper.toModelList(dtos);

       //then
       Assertions.assertNotNull(models);
       Assertions.assertEquals(1, models.size());
       Assertions.assertEquals(dto.getId(), models.get(0).getId());
       Assertions.assertEquals(dto.getName(), models.get(0).getName());
   }
}
Saiki, yen kita nganakake tes, kabeh bakal bisa kaya sing dikarepake, amarga ing LectureListMapperImpl kita ngliwati LectureMapper sing dibutuhake ... Kamenangan! Ora angel kanggo sampeyan, nanging aku seneng: Kanca-kanca, kabeh kaya biasane, langganan akun GitHubku , menyang akun Telegramku . Ing kana aku ngirimake asil kegiatanku, ana sing migunani banget) Aku ngajak sampeyan gabung ing grup diskusi saluran telegram . Dadi yen ana sing duwe pitakonan teknis, dheweke bisa njaluk jawaban ing kana. Format iki menarik kanggo kabeh wong, sampeyan bisa maca sing ngerti apa lan entuk pengalaman.

Kesimpulan

Minangka bagéan saka artikel iki, kita kenal karo produk sing perlu lan asring digunakake minangka Mapstruct. We figured metu apa iku, kok lan carane. Nggunakake conto nyata, kita felt apa bisa rampung lan carane bisa diganti. Kita uga ndeleng carane nyiyapake injeksi kacang buncis liwat konstruktor, supaya bisa nguji mappers kanthi bener. Kolega saka Mapstruct ngidini pangguna produk kanggo milih persis carane nyuntikake mappers, sing mesthi kita matur nuwun. Nanging, sanajan kasunyatane Spring nyaranake nyuntikake kacang buncis liwat konstruktor, wong lanang saka Mapstruct wis nyetel injeksi liwat lapangan kanthi standar. Kok ngono? Ora ana wangsulan. Aku curiga ana uga alasan sing kita ora ngerti, lan mulane dheweke nindakake kanthi cara iki. Lan kanggo ngerteni saka dheweke, aku nggawe masalah GitHub ing repositori produk resmi.
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION