如何为通过Spring注入的mapstruct抽象映射器编写Junit测试

时间:2017-07-24 08:13:34

标签: spring unit-testing junit spring-test mapstruct

我正在使用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,但也没有骰子。

  

无法实例化名为“service”的@InjectMocks字段。你没有   在字段声明中提供了实例,所以我尝试构造了   实例。但是,我失败的原因是:'MainMapper类型是   一个抽象类。

通过Spring @Autowired

  

引起:   org.springframework.beans.factory.NoSuchBeanDefinitionException:没有   'com.mappers.MainMapper'类型的限定bean可用:expected   至少有1个符合autowire候选资格的bean。依赖   注释:   {@ org.springframework.beans.factory.annotation.Autowired(所需=真)}

我猜这可能与注释处理器有关,并且在我启动测试时没有生成映射器。 我找到了this class as example

但是,在没有最终版本的1.2之前,类AnnotationProcessorTestRunner似乎不可用。

所以我的问题是如何编写Junit测试来测试我在我的代码中通过Spring注入使用的mapstruct抽象类映射器。

5 个答案:

答案 0 :(得分:9)

回应@Richard Lewan的评论,这里是我如何使用2个subMappers为抽象类ConfigurationMapper声明我的测试类

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

您使用SpringBootTest注释中生成的impl 然后注入要测试的类

@Autowired
private ConfigurationMapper configurationMapper;

如果您需要更多信息,请告诉我,但从那里可以直截了当。 我没有模仿subMapper,因为我最好一次测试所有的映射过程。

答案 1 :(得分:3)

您遇到了多个问题:

  1. 您应该仅将Mappers#getMapper(Class)与默认componentModel一起使用,否则映射器将无法正确实例化。如果您在那里获得RuntimeException,则意味着未生成实现类。确保您的设置正确
  2. 您需要针对实现MainMapperImpl进行测试,而不是针对抽象类进行测试。
  3. 如果您想使用spring bean进行测试,那么您需要使用正确的ComponentScan并确保实现和使用的映射器可以自动连接。
  4. 您链接的类是错误的测试类,与您的测试用例无关。看看this集成测试用例的Spring集成。

    AnnotationProcessorTestRunner是我们测试的一部分,用于测试注释处理器,并从一开始就存在。它不是版本的一部分。

答案 2 :(得分:3)

@TheBakker的答案的补充:如果您不需要整个SpringBoot堆栈,则可以使用@SpringBootTest作为@ContextConfiguration的更轻松的替代方法。他的示例如下所示:

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

答案 3 :(得分:1)

假设:

  • 您的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.
    }

}

答案 4 :(得分:0)

使用 Mockito:

@Spy
private EntityMapper entityMapper = Mappers.getMapper(MyMapper.class);

并记住在您的测试类中注入模拟,例如:

@InjectMocks
private MyClassUnderTest myClassUnderTest