模型映射器适用于实时代码,但在 JUNIT 期间不起作用
Model Mapper works on Live Code but is not working during JUNITs
背景
我有一个简单的 SpringBoot 应用程序,我在其中测试从 DTO 到我的域对象的更新。当然 - 我正在使用 ModelMapper 从 DTO->Entity 进行转换。我 运行 关注的问题是,虽然 ModelMapper 在实时 运行 中工作得很好,但它在 JUNIT 期间不工作。在 JUNIT 和 LIVE 运行 期间,我在我的配置文件的 initBaseModelMapper
中放置了一个断点,断点成功命中。但在 JUNITS 中,在实际映射期间 - null
值仍在应用于域实体,但在实时 运行 期间没有应用,这完美地工作。
配置
@Configuration
public class ModelMapperConfiguration {
@Bean(name = "myEntityMapper")
public ModelMapper modelMapper() {
return initBaseModelMapper();
}
public static ModelMapper initBaseModelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setPropertyCondition(Conditions.isNotNull());
modelMapper.getConfiguration().setSkipNullEnabled(true); // Tried without this as well
return modelMapper; // Gets hit during LIVE and JUNITS
}
}
主要Class 待测方法
public class MyCaseService {
@Autowired
@Qualifier("myEntityMapper")
private ModelMapper modelMapper;
@Override
@Transactional
public @ResponseBody
MyCaseEntity updateMyCase(
@Valid final String myCaseId,
@Valid MyCaseDTO myCase) throws Exception {
MyCaseEntity existingEntity = entityRepository.find(myCaseId);
modelMapper.map(myCase, existingEntity);
return existingEntity;
}
JUNIT
我在 ModelConfiguration
中放置了一个断点,我可以看到它正在初始化,就像代码 运行 正在运行时一样。但是,出于某种原因,ModelMapper 忽略了空字段的跳过,这与 运行ning live
不同
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes= {ModelMapperConfiguration.class})
public class MyCaseServiceTest {
@InjectMocks
private MyCaseService testSubject;
@Spy
@Qualifier("myEntityMapper")
private ModelMapper modelMapper;
@Before
public void setUp() {
// Initialized `testEntityCase` etc with Id etc
}
@Test
public void testUpdate() throws Exception {
Mockito.when(entityRepository.find(Mockito.any())).thenReturn(testEntityCase);
MyCaseEntity myCase = testSubject.updateMyCase(
"1",
testCaseDTO);
assertEquals(1L, myCase.getId().longValue()); // <- Test Fails with NullPointer. Id becomes null during JUNIT.
}
克服这些问题的一种方法是自动装配私有成员的 MyCaseService 的构造函数
public class MyCaseService {
private ModelMapper modelMapper;
@Autowired
MyCaserService(@Qualifier("myEntityMapper") ModelMapper modelMapper) {
this.modelMapper = modelMapper;
}
@Override
@Transactional
public @ResponseBody
MyCaseEntity updateMyCase(
@Valid final String myCaseId,
@Valid MyCaseDTO myCase) throws Exception {
MyCaseEntity existingEntity = entityRepository.find(myCaseId);
modelMapper.map(myCase, existingEntity);
return existingEntity;
}
}
在测试中您可以使用 Spy 创建服务
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes= {ModelMapperConfiguration.class})
public class MyCaseServiceTest {
@Spy
@Qualifier("myEntityMapper")
private ModelMapper modelMapper;
private MyCaseService testSubject;
@Before
public void setUp() {
testSubject = new MyCaseService(modelMapper);
// Initialized `testEntityCase` etc with Id etc
}
...
背景
我有一个简单的 SpringBoot 应用程序,我在其中测试从 DTO 到我的域对象的更新。当然 - 我正在使用 ModelMapper 从 DTO->Entity 进行转换。我 运行 关注的问题是,虽然 ModelMapper 在实时 运行 中工作得很好,但它在 JUNIT 期间不工作。在 JUNIT 和 LIVE 运行 期间,我在我的配置文件的 initBaseModelMapper
中放置了一个断点,断点成功命中。但在 JUNITS 中,在实际映射期间 - null
值仍在应用于域实体,但在实时 运行 期间没有应用,这完美地工作。
配置
@Configuration
public class ModelMapperConfiguration {
@Bean(name = "myEntityMapper")
public ModelMapper modelMapper() {
return initBaseModelMapper();
}
public static ModelMapper initBaseModelMapper() {
ModelMapper modelMapper = new ModelMapper();
modelMapper.getConfiguration().setPropertyCondition(Conditions.isNotNull());
modelMapper.getConfiguration().setSkipNullEnabled(true); // Tried without this as well
return modelMapper; // Gets hit during LIVE and JUNITS
}
}
主要Class 待测方法
public class MyCaseService {
@Autowired
@Qualifier("myEntityMapper")
private ModelMapper modelMapper;
@Override
@Transactional
public @ResponseBody
MyCaseEntity updateMyCase(
@Valid final String myCaseId,
@Valid MyCaseDTO myCase) throws Exception {
MyCaseEntity existingEntity = entityRepository.find(myCaseId);
modelMapper.map(myCase, existingEntity);
return existingEntity;
}
JUNIT
我在 ModelConfiguration
中放置了一个断点,我可以看到它正在初始化,就像代码 运行 正在运行时一样。但是,出于某种原因,ModelMapper 忽略了空字段的跳过,这与 运行ning live
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes= {ModelMapperConfiguration.class})
public class MyCaseServiceTest {
@InjectMocks
private MyCaseService testSubject;
@Spy
@Qualifier("myEntityMapper")
private ModelMapper modelMapper;
@Before
public void setUp() {
// Initialized `testEntityCase` etc with Id etc
}
@Test
public void testUpdate() throws Exception {
Mockito.when(entityRepository.find(Mockito.any())).thenReturn(testEntityCase);
MyCaseEntity myCase = testSubject.updateMyCase(
"1",
testCaseDTO);
assertEquals(1L, myCase.getId().longValue()); // <- Test Fails with NullPointer. Id becomes null during JUNIT.
}
克服这些问题的一种方法是自动装配私有成员的 MyCaseService 的构造函数
public class MyCaseService {
private ModelMapper modelMapper;
@Autowired
MyCaserService(@Qualifier("myEntityMapper") ModelMapper modelMapper) {
this.modelMapper = modelMapper;
}
@Override
@Transactional
public @ResponseBody
MyCaseEntity updateMyCase(
@Valid final String myCaseId,
@Valid MyCaseDTO myCase) throws Exception {
MyCaseEntity existingEntity = entityRepository.find(myCaseId);
modelMapper.map(myCase, existingEntity);
return existingEntity;
}
}
在测试中您可以使用 Spy 创建服务
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes= {ModelMapperConfiguration.class})
public class MyCaseServiceTest {
@Spy
@Qualifier("myEntityMapper")
private ModelMapper modelMapper;
private MyCaseService testSubject;
@Before
public void setUp() {
testSubject = new MyCaseService(modelMapper);
// Initialized `testEntityCase` etc with Id etc
}
...