如何测试在 Spring Boot 中使用 Mapstruct 映射器的服务 class 方法?
How to test Service class methods which uses Mapstruct mappers in Springboot?
@Mapper(uses = SomeMapper.class,imports = Date.class)
public interface DomainModelMapper {
Model domainToModel(Domain domain);
@Mapping(target="dateUpdated", source="dateUpdated" ,defaultExpression = "java(Date.from(java.time.OffsetDateTime.now().toInstant()))")
@Mapping(target="id.key",source="id.key",defaultExpression = "java(com.datastax.driver.core.utils.UUIDs.timeBased())")
Domain modelToDomain(Model model);
}
我有一个映射器 class 可以进行一些日期转换
public class SomeMapper {
public Date OffsetDateTimeToDate(OffsetDateTime offsetDateTime) {
return offsetDateTime != null ? Date.from(offsetDateTime.toInstant()):null;
}
public OffsetDateTime DateToOffsetDateTime(Date date) {
return date != null ? date.toInstant().atOffset(ZoneOffset.UTC) : null;
}
}
这是我的服务class,我在其中使用 DomainModelMapper
@Service
public class SomeServiceImpl implements SomeService {
@Autowired
someRepository someRepository;
private final DomainModelMapper domainToModelMapper =
Mappers.getMapper(DomainModelMapper.class);
@Override
public Model saveSomething(Model model) {
return DomainModelMapper.domainToModel(someRepository
.save(DomainModelMapper.modelToDomain(model)));
}
如何对 saveSomething(Model model) 方法进行单元测试?我如何注入 Mapstruct classes 或模拟它们?
如果您将 @Mapper
接口作为基于 Spring 的组件模型,那么它可以通过 @Autowired
注释自动装配。在 4.2. Using dependency injection
阅读更多内容
@Mapper(uses = SomeMapper.class,imports = Date.class, componentModel = "spring")
public interface DomainModelMapper {
// IMPLEMENTATION
}
@Service
public class SomeServiceImpl implements SomeService {
@Autowired
SomeRepository someRepository;
@Autowired
DomainModelMapper domainModelMapper;
// THE REST OF THE IMPLEMENTATION
}
测试变得相当容易,因为所有 beans 也可以使用 @Autowired
注释注入 @SpringBootTest
。
DomainModelMapper
可以自动装配并按原样在单元测试中使用,并依赖于它的实现
-
SomeRepository
应该使用 @MockBean
来模拟,它会覆盖现有的 bean,或者如果该类型的 none 存在则创建一个新的 bean...或者像实现中那样自动装配如果您在测试阶段使用内存数据库,例如 H2。
无论如何,测试class将准备好进行测试。
@SpringBootTest
public class SomeServiceTest {
@Autowired // or @MockBean
SomeRepository someRepository;
@Autowired // no need to mock it
DomainModelMapper domainModelMapper;
@Test
public void test() {
// TEST
}
}
@Mapper(uses = SomeMapper.class,imports = Date.class)
public interface DomainModelMapper {
Model domainToModel(Domain domain);
@Mapping(target="dateUpdated", source="dateUpdated" ,defaultExpression = "java(Date.from(java.time.OffsetDateTime.now().toInstant()))")
@Mapping(target="id.key",source="id.key",defaultExpression = "java(com.datastax.driver.core.utils.UUIDs.timeBased())")
Domain modelToDomain(Model model);
}
我有一个映射器 class 可以进行一些日期转换
public class SomeMapper {
public Date OffsetDateTimeToDate(OffsetDateTime offsetDateTime) {
return offsetDateTime != null ? Date.from(offsetDateTime.toInstant()):null;
}
public OffsetDateTime DateToOffsetDateTime(Date date) {
return date != null ? date.toInstant().atOffset(ZoneOffset.UTC) : null;
}
}
这是我的服务class,我在其中使用 DomainModelMapper
@Service
public class SomeServiceImpl implements SomeService {
@Autowired
someRepository someRepository;
private final DomainModelMapper domainToModelMapper =
Mappers.getMapper(DomainModelMapper.class);
@Override
public Model saveSomething(Model model) {
return DomainModelMapper.domainToModel(someRepository
.save(DomainModelMapper.modelToDomain(model)));
}
如何对 saveSomething(Model model) 方法进行单元测试?我如何注入 Mapstruct classes 或模拟它们?
如果您将 @Mapper
接口作为基于 Spring 的组件模型,那么它可以通过 @Autowired
注释自动装配。在 4.2. Using dependency injection
@Mapper(uses = SomeMapper.class,imports = Date.class, componentModel = "spring")
public interface DomainModelMapper {
// IMPLEMENTATION
}
@Service
public class SomeServiceImpl implements SomeService {
@Autowired
SomeRepository someRepository;
@Autowired
DomainModelMapper domainModelMapper;
// THE REST OF THE IMPLEMENTATION
}
测试变得相当容易,因为所有 beans 也可以使用 @Autowired
注释注入 @SpringBootTest
。
DomainModelMapper
可以自动装配并按原样在单元测试中使用,并依赖于它的实现-
SomeRepository
应该使用@MockBean
来模拟,它会覆盖现有的 bean,或者如果该类型的 none 存在则创建一个新的 bean...或者像实现中那样自动装配如果您在测试阶段使用内存数据库,例如 H2。
无论如何,测试class将准备好进行测试。
@SpringBootTest
public class SomeServiceTest {
@Autowired // or @MockBean
SomeRepository someRepository;
@Autowired // no need to mock it
DomainModelMapper domainModelMapper;
@Test
public void test() {
// TEST
}
}