ihe*_*heb 7 java unit-testing mockito mapstruct
我使用 MapStruct 来映射我的实体,并且我正在使用 Mockito 模拟我的对象。
我想测试一个包含 mapStruct 映射的方法。问题是嵌套映射器在我的单元测试中始终为空(在应用程序中运行良好)
这是我的映射器声明:
@Mapper(componentModel = "spring", uses = MappingUtils.class)
public interface MappingDef {
UserDto userToUserDto(User user)
}
Run Code Online (Sandbox Code Playgroud)
这是我的嵌套映射器
@Mapper(componentModel = "spring")
public interface MappingUtils {
//.... other mapping methods used by userToUserDto
Run Code Online (Sandbox Code Playgroud)
这是我要测试的方法:
@Service
public class SomeClass{
@Autowired
private MappingDef mappingDef;
public UserDto myMethodToTest(){
// doing some business logic here returning a user
// User user = Some Business Logic
return mappingDef.userToUserDto(user)
}
Run Code Online (Sandbox Code Playgroud)
这是我的单元测试:
@RunWith(MockitoJUnitRunner.class)
public class NoteServiceTest {
@InjectMocks
private SomeClass someClass;
@Spy
MappingDef mappingDef = Mappers.getMapper(MappingDef.class);
@Spy
MappingUtils mappingUtils = Mappers.getMapper(MappingUtils.class);
//initMocks is omitted for brevity
@test
public void someTest(){
UserDto userDto = someClass.myMethodToTest();
//and here some asserts
}
Run Code Online (Sandbox Code Playgroud)
mappingDef被正确注入,但mappingUtils始终为空
免责声明:这不是这个问题的重复。他正在使用@Autowire,因此他正在加载 spring 上下文,因此他正在进行集成测试。我在做单元测试,所以我不使用@Autowired
我不想做mappingDef,mappingUtils @Mock所以我不需要when(mappingDef.userToUserDto(user)).thenReturn(userDto)在每个用例中做
Lee*_*eol 14
如果您愿意使用 Spring test util,那么使用org.springframework.test.util.ReflectionTestUtils.
MappingDef mappingDef = Mappers.getMapper(MappingDef.class);
MappingUtils mappingUtils = Mappers.getMapper(MappingUtils.class);
...
// Somewhere appropriate
@Before
void before() {
ReflectionTestUtils.setField(
mappingDef,
"mappingUtils",
mappingUtils
)
}
Run Code Online (Sandbox Code Playgroud)
Sja*_*aak 10
强制 MapStruct 通过构造函数注入生成实现
@Mapper(componentModel = "spring", uses = MappingUtils.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface MappingDef {
UserDto userToUserDto(User user)
}
Run Code Online (Sandbox Code Playgroud)
@Mapper(componentModel = "spring", injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface MappingUtils {
//.... other mapping methods used by userToUserDto
Run Code Online (Sandbox Code Playgroud)
使用构造函数注入,以便您可以使用映射器构造被测试的类。
@Service
public class SomeClass{
private final MappingDef mappingDef;
@Autowired
public SomeClass(MappingDef mappingDef) {
this.mappingDef = mappingDef;
}
public UserDto myMethodToTest(){
// doing some business logic here returning a user
// User user = Some Business Logic
return mappingDef.userToUserDto(user)
}
Run Code Online (Sandbox Code Playgroud)
测试一些类。注意:它不是您在这里测试的映射器,因此可以模拟映射器。
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
private SomeClass classUnderTest;
@Mock
private MappingDef mappingDef;
@Before init() {
classUnderTest = new SomeClass(mappingDef);
// defaultMockBehaviour:
when(mappingDef.userToUserDto(anyObject(User.class).thenReturn(new UserDto());
}
@test
public void someTest(){
UserDto userDto = someClass.myMethodToTest();
//and here some asserts
}
Run Code Online (Sandbox Code Playgroud)
在真正的单元测试中,还要测试映射器。
@RunWith(MockitoJUnitRunner.class)
public class MappingDefTest {
MappingDef classUnderTest;
@Before
void before() {
// use some reflection to get an implementation
Class aClass = Class.forName( MappingDefImpl.class.getCanonicalName() );
Constructor constructor =
aClass.getConstructor(new Class[]{MappingUtils.class});
classUnderTest = (MappingDef)constructor.newInstance( Mappers.getMapper( MappingUtils.class ));
}
@Test
void test() {
// test all your mappings (null's in source, etc)..
}
Run Code Online (Sandbox Code Playgroud)
无需使用反射。对我来说最简单的方法如下:
@RunWith(MockitoJUnitRunner.class)
public class NoteServiceTest {
@InjectMocks
private SomeClass someClass;
@Spy
@InjectMocks
MappingDef mappingDef = Mappers.getMapper(MappingDef.class);
@Spy
MappingUtils mappingUtils = Mappers.getMapper(MappingUtils.class);
Run Code Online (Sandbox Code Playgroud)
然而,这仅适用于嵌套映射器的第一层。如果您有一个使用第三个映射器的映射器,那么您需要使用将ReflectionTestUtils第三个映射器注入到第二个映射器中。
| 归档时间: |
|
| 查看次数: |
8916 次 |
| 最近记录: |