如何在测试中使用真实的MapStruct映射器方法?

huangapple go评论88阅读模式
英文:

How to use a real mapstruct mapper method in test?

问题

我有一个类,其中一个方法中使用了映射器来将结果返回为DTO列表。我想使用一个真正的映射器方法,因为它可以让我检查真实的功能。

这是我的测试类:

  1. @ExtendWith(MockitoExtension.class)
  2. public class UserCardServiceTest {
  3. @Mock
  4. private MyCardRepository myCardRepository;
  5. @Mock(answer = Answers.CALLS_REAL_METHODS)
  6. private MyMapper myMapper;
  7. @InjectMocks
  8. private MyServiceImpl underTest;
  9. // ...其他部分...
  10. }

我要测试的方法如下:

  1. @RequiredArgsConstructor
  2. public class MyServiceImpl implements MyCardService {
  3. private final MyCardRepository myCardRepository;
  4. private final MyMapper myMapper;
  5. @Override
  6. public List<CardDto> getActiveUserCardsById(final long userId) {
  7. List<CardEntity> listOfEntities = myRepository.findAllByUserId(userId);
  8. listOfEntities.stream().filter(validationService::isCardExpired)
  9. .forEach(userCard -> userCard.setBlocked(true));
  10. List<CardEntity> sorted = listOfEntities.stream()
  11. .sorted(o -> o.getName().toUpperCase())
  12. .toList();
  13. return myMapper
  14. .listOfCardEntitiesToCardDto(sorted);
  15. }
  16. }

但是,我得到以下结果:

  1. java.lang.AssertionError:
  2. Expected size: 4 but was: 0 in:
  3. []

有人能否告诉我如何调用一个真正的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:

  1. @ExtendWith(MockitoExtension.class)
  2. public class UserCardServiceTest {
  3. @Mock
  4. private MyCardRepository myCardRepository;
  5. @Mock(answer = Answers.CALLS_REAL_METHODS)
  6. private MyMapper myMapper;
  7. @InjectMocks
  8. private MyServiceImpl underTest;
  9. @BeforeEach
  10. void setUp() {
  11. listOfExpiredUserCardEntities = new ArrayList&lt;&gt;(List.of(
  12. getValidUserCardEntity()
  13. .setExpirationDate(LocalDate.now().minusDays(1))
  14. .setBlocked(false),
  15. getValidUserCardEntity()
  16. .setExpirationDate(LocalDate.now().minusWeeks(1))
  17. .setBlocked(false),
  18. getValidUserCardEntity()
  19. .setExpirationDate(LocalDate.now().minusYears(1))
  20. .setBlocked(false),
  21. getValidUserCardEntity()
  22. .setExpirationDate(LocalDate.now().minusMonths(1))
  23. .setBlocked(false));
  24. }
  25. @Test
  26. void shouldChangeStatusIfCardExpired() {
  27. given(myCardRepository.findAllByUserId(1L))
  28. .willReturn(listOfCardEntities);
  29. assertThat(underTest.getActiveUserCardsById(1L)).isNotNull().hasSize(4);
  30. assertThat(underTest.getActiveUserCardsById(1))
  31. .extracting(CardDto::isBlocked)
  32. .containsExactly(true, true, true, true)
  33. .doesNotContainNull();
  34. }

My method to test:

  1. @RequiredArgsConstructor
  2. public class MyServiceImpl implements MyCardService {
  3. private final MyCardRepository myCardRepository;
  4. private final MyMapper myMapper;
  5. @Override
  6. public List&lt;CardDto&gt; getActiveUserCardsById(final long userId) {
  7. List&lt;CardEntity&gt; listOfEntities = myRepository.findAllByUserId(userId);
  8. listOfEntities.stream().filter(validationService::isCardExpired)
  9. .forEach(userCard -&gt; userCard.setBlocked(true));
  10. List&lt;CardEntity&gt; sorted = listOfEntities.stream()
  11. .sorted(o -&gt; o.getName().toUpperCase())
  12. .toList();
  13. return myMapper
  14. .listOfCardEntitiesToCardDto(sorted);
  15. }

But as a result I get:

  1. java.lang.AssertionError:
  2. Expected size: 4 but was: 0 in:
  3. []

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

我在我的项目中也遇到了相同的问题。我使用了以下解决方案:

  1. import org.mapstruct.factory.Mappers;
  2. import org.mockito.InjectMocks;
  3. import org.mockito.Mock;
  4. import org.mockito.Spy;
  5. ......
  6. @Mock
  7. private MyCardRepository myCardRepository;
  8. @Spy
  9. private MyMapper myMapper = Mappers.get(MyMapper.class);
  10. @InjectMocks
  11. private MyServiceImpl underTest;

这只需使用 @ExtendWith(MockitoExtension.class) 即可正常工作,无需启动整个SpringBoot上下文 如何在测试中使用真实的MapStruct映射器方法?

英文:

I had the same problem in my projects. I am using the following solution:

  1. import org.mapstruct.factory.Mappers;
  2. import org.mockito.InjectMocks;
  3. import org.mockito.Mock;
  4. import org.mockito.Spy;
  5. .....
  6. @Mock
  7. private MyCardRepository myCardRepository;
  8. @Spy
  9. private MyMapper myMapper = Mappers.get(MyMapper.class);
  10. @InjectMocks
  11. private MyServiceImpl underTest;

This works with only @ExtendWith(MockitoExtension.class). There is no need to start the entire SpringBoot Context 如何在测试中使用真实的MapStruct映射器方法?

huangapple
  • 本文由 发表于 2023年2月6日 16:23:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/75358872.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定