英文:
How to use a real mapstruct mapper method in test?
问题
我有一个类,其中一个方法中使用了映射器来将结果返回为DTO列表。我想使用一个真正的映射器方法,因为它可以让我检查真实的功能。
这是我的测试类:
@ExtendWith(MockitoExtension.class)
public class UserCardServiceTest {
@Mock
private MyCardRepository myCardRepository;
@Mock(answer = Answers.CALLS_REAL_METHODS)
private MyMapper myMapper;
@InjectMocks
private MyServiceImpl underTest;
// ...其他部分...
}
我要测试的方法如下:
@RequiredArgsConstructor
public class MyServiceImpl implements MyCardService {
private final MyCardRepository myCardRepository;
private final MyMapper myMapper;
@Override
public List<CardDto> getActiveUserCardsById(final long userId) {
List<CardEntity> listOfEntities = myRepository.findAllByUserId(userId);
listOfEntities.stream().filter(validationService::isCardExpired)
.forEach(userCard -> userCard.setBlocked(true));
List<CardEntity> sorted = listOfEntities.stream()
.sorted(o -> o.getName().toUpperCase())
.toList();
return myMapper
.listOfCardEntitiesToCardDto(sorted);
}
}
但是,我得到以下结果:
java.lang.AssertionError:
Expected size: 4 but was: 0 in:
[]
有人能否告诉我如何调用一个真正的MapStruct映射器方法,而不是准备好的答案。是否可以只使用@ExtendWith(MockitoExtension.class)来实现?
【注意】:上述代码示例中的 "<" 和 ">" 字符是 HTML 实体编码,用于表示尖括号 "<" 和 ">"。在实际代码中应使用正常的尖括号。
英文:
I have a class that uses mapper in one of the methods to return the result as a list of DTOs.
I want to use a real mapper method as it gives me possibility to check real functionality.
It's my test class:
@ExtendWith(MockitoExtension.class)
public class UserCardServiceTest {
@Mock
private MyCardRepository myCardRepository;
@Mock(answer = Answers.CALLS_REAL_METHODS)
private MyMapper myMapper;
@InjectMocks
private MyServiceImpl underTest;
@BeforeEach
void setUp() {
listOfExpiredUserCardEntities = new ArrayList<>(List.of(
getValidUserCardEntity()
.setExpirationDate(LocalDate.now().minusDays(1))
.setBlocked(false),
getValidUserCardEntity()
.setExpirationDate(LocalDate.now().minusWeeks(1))
.setBlocked(false),
getValidUserCardEntity()
.setExpirationDate(LocalDate.now().minusYears(1))
.setBlocked(false),
getValidUserCardEntity()
.setExpirationDate(LocalDate.now().minusMonths(1))
.setBlocked(false));
}
@Test
void shouldChangeStatusIfCardExpired() {
given(myCardRepository.findAllByUserId(1L))
.willReturn(listOfCardEntities);
assertThat(underTest.getActiveUserCardsById(1L)).isNotNull().hasSize(4);
assertThat(underTest.getActiveUserCardsById(1))
.extracting(CardDto::isBlocked)
.containsExactly(true, true, true, true)
.doesNotContainNull();
}
My method to test:
@RequiredArgsConstructor
public class MyServiceImpl implements MyCardService {
private final MyCardRepository myCardRepository;
private final MyMapper myMapper;
@Override
public List<CardDto> getActiveUserCardsById(final long userId) {
List<CardEntity> listOfEntities = myRepository.findAllByUserId(userId);
listOfEntities.stream().filter(validationService::isCardExpired)
.forEach(userCard -> userCard.setBlocked(true));
List<CardEntity> sorted = listOfEntities.stream()
.sorted(o -> o.getName().toUpperCase())
.toList();
return myMapper
.listOfCardEntitiesToCardDto(sorted);
}
But as a result I get:
java.lang.AssertionError:
Expected size: 4 but was: 0 in:
[]
Can anyone say how to invoke a real mapstruct mapper method, but not prepared answer.
Is it possible to do with only @ExtendWith(MockitoExtension.class)?
答案1
得分: 1
我在我的项目中也遇到了相同的问题。我使用了以下解决方案:
import org.mapstruct.factory.Mappers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
......
@Mock
private MyCardRepository myCardRepository;
@Spy
private MyMapper myMapper = Mappers.get(MyMapper.class);
@InjectMocks
private MyServiceImpl underTest;
这只需使用 @ExtendWith(MockitoExtension.class)
即可正常工作,无需启动整个SpringBoot上下文
英文:
I had the same problem in my projects. I am using the following solution:
import org.mapstruct.factory.Mappers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
.....
@Mock
private MyCardRepository myCardRepository;
@Spy
private MyMapper myMapper = Mappers.get(MyMapper.class);
@InjectMocks
private MyServiceImpl underTest;
This works with only @ExtendWith(MockitoExtension.class)
. There is no need to start the entire SpringBoot Context
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论