web-dev-qa-db-ja.com

Spring経由で注入されたmapstruct抽象マッパーのJunitテストを書く方法

私はMapStruct、mapstruct-jdk8バージョン1.1.0.Finalを使用していて、Springを介して注入する抽象クラスを定義しています。

Junit Testを介してそれらをテストする方法を探していますか?私は基本的に2つのサブマッパーを使用するメインマッパーを持っています

@Mapper(componentModel = "spring", uses = {SubMapper1.class, SubMapper2.class})
public abstract class MainMapper {

  @Mapping(target = "field1", qualifiedByName = {"MyMapper2Name", "toEntity"})
  public abstract MyEntity toEntity(MyDto pDto);

  public MyDto fromEntity(MyEntity pEntity) {
     // Specific code, hence why I use Abstract class instead of interface. 
  }
}

私はいくつかのことを試しましたが、それをテストするためにマッパーを正しくインスタンス化することができません。

@RunWith(SpringRunner.class)
public class MainMapperTest {

    private MainMapper service = Mappers.getMapper(MainMapper.class);

    @Test
    public void testToEntity() throws Exception {
.....

Java.lang.RuntimeException:Java.lang.ClassNotFoundException:com.mappers.MainMapperの実装が見つかりません

@InjectMockでも試しましたが、ダイスもありません。

「サービス」という名前の@InjectMocksフィールドをインスタンス化できません。フィールド宣言でインスタンスを提供していないため、インスタンスを作成しようとしました。ただし、次の理由で失敗しました。タイプ 'MainMapperは抽象クラスです。

そしてSpring @Autowired経由

原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:タイプ「com.mappers.MainMapper」の適格なBeanがありません:オートワイヤー候補として適格な少なくとも1つのBeanが必要です。依存関係アノテーション:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}

これは注釈プロセッサと関係があるのではないかと思います。テストを起動したときにマッパーが生成されていません。私は このクラスの例として を見つけました。

ただし、クラスAnnotationProcessorTestRunnerは、最終リリースがまだない1.2以前では使用できないようです。

したがって、私の質問は、コードでSpringインジェクションを介して使用するmapstruct抽象クラスマッパーをテストするためのJunitテストをどのように記述するかです。

10
TheBakker

@Richard Lewanのコメントに応じて、2つのサブマッパーを使用して、抽象クラスConfigurationMapperのテストクラスをどのように宣言したかを示します。

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ConfigurationMapperImpl.class, SubMapper1Impl.class, SubMapper2Impl.class})
public class ConfigurationMapperTest {

Impl生成されたクラスをSpringBootTestアノテーションで使用してから、テストするクラスを注入します。

@Autowired
private ConfigurationMapper configurationMapper;

さらに情報が必要な場合はお知らせください。そこからは簡単です。すべてのマッピングプロセスを一度にテストする方が良いため、私はsubMapperをモックしませんでした。

13
TheBakker

複数の問題が発生しています:

  1. Mappers#getMapper(Class)は、デフォルトのcomponentModelでのみ使用する必要があります。そうしないと、マッパーが正しくインスタンス化されません。 RuntimeExceptionを取得している場合、実装クラスが生成されなかったことを意味します。セットアップが正しいことを確認してください
  2. 抽象クラスではなく、実装MainMapperImplに対してテストする必要があります。
  3. Spring Beanでテストする場合は、正しいComponentScanを使用し、実装と使用するマッパーを自動配線できることを確認する必要があります。

リンクしたクラスは間違ったテストクラスであり、テストケースとは関係ありません。 this Spring統合の統合テストケースをご覧ください。

AnnotationProcessorTestRunnerはテストの一部であり、注釈プロセッサのテストに使用され、最初から存在しています。これはリリースの一部ではありません。

4
Filip

仮定すると:

  • MainMapperマッパーが@Component ConverterUsingMainMapperに挿入されます

次の例を使用できます。

@RunWith(SpringRunner.class)
@ContextConfiguration
public class ConsentConverterTest {

    @Autowired
    MainMapper MainMapper;

    @Autowired
    ConverterUsingMainMapper converter;

    @Configuration
    public static class Config {

        @Bean
        public ConverterUsingMainMapper converterUsingMainMapper() {
            return new ConverterUsingMainMapper();
        }

        @Bean
        public MainMapper mainMapper() {
            return Mappers.getMapper(MainMapper.class);
        }
    }


    @Test
    public void test1() {
        // ... your test.
    }

}
2
Witold Kaczurba

@TheBakkerの回答への追加:SpringBootが不要な場合は、@SpringBootTestの代わりに@ContextConfigurationを使用できます。彼の例は次のようになります。

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {ConfigurationMapperImpl.class, SubMapper1Impl.class, SubMapper2Impl.class})
public class ConfigurationMapperTest {
...
0
t0r0X