“Spring Framework – Mock is not mocking”

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

Spring Framework - Mock is not mocking

问题

我有一个Spring MvC应用程序。(Spring Framework是Java平台的应用程序框架和控制反转容器),具有以下测试代码:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class AutorisationServiceTest {
  3. @Autowired
  4. @InjectMocks
  5. private IAutorisationService service;
  6. @Mock
  7. PersonneRepository personneRepository = Mockito.mock(PersonneRepository.class);
  8. @Before
  9. public void setup() {
  10. }
  11. @Test
  12. public void should_Find_GardeWith2Affectations() throws IOException {
  13. when(personneRepository.getAll(anyString())).thenReturn(DataLoader.mockData());
  14. service.getAll("rules");
  15. }
  16. }
  1. @Service
  2. public class AutorisationService implements IAutorisationService {
  3. private final PersonneRepository personneRepository;
  4. public AutorisationService(PersonneRepository personneRepository) {
  5. this.personneRepository = personneRepository;
  6. }
  7. @Override
  8. public List<User> getAll(String where) {
  9. return personneRepository.getAll(where);
  10. }
  11. // ...
  12. }

但是,当我运行测试时,似乎没有对存储库进行模拟。

英文:

I have a Spring MvC app. (The Spring Framework is an application framework and inversion of control container for the Java platform) with this test:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class AutorisationServiceTest {
  3. @Autowired
  4. @InjectMocks
  5. private IAutorisationService service;
  6. @Mock
  7. PersonneRepository personneRepository = Mockito.mock(PersonneRepository.class);
  8. @Before
  9. public void setup() {
  10. }
  11. @Test
  12. public void should_Find_GardeWith2Affectations() throws IOException {
  13. when(personneRepository.getAll(anyString())).thenReturn(DataLoader.mockData());
  14. service.getAll(&quot;rules&quot;);
  15. }
  16. }
  17. @Service
  18. public class AutorisationService implements IAutorisationService {
  19. private final PersonneRepository personneRepository;
  20. public AutorisationService(PersonneRepository personneRepository) {
  21. this.personneRepository = personneRepository;
  22. }
  23. @Override
  24. public List&lt;User&gt; getAll(String where) {
  25. return personneRepository.getAll(where));
  26. }
  27. ...
  28. }

but when I run the test it seems no to mock the repo

答案1

得分: 1

这个回答是关于 testng 的:

MockitoTestExecutionListener 初始化模拟对象,你需要使用 @MockBean 注解。

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @TestExecutionListeners(MockitoTestExecutionListener.class)
  3. public class AutorisationServiceTest {
  4. @MockBean
  5. PersonneRepository personneRepository;

另外,别忘了添加 ResetMocksTestExecutionListener 来防止测试之间的持久模拟对象影响(参见这个问题)。

英文:

This answer is for testng:

MockitoTestExecutionListener initializes mocks, and you need to use @MockBean annotation.

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. @TestExecutionListeners(MockitoTestExecutionListener.class)
  3. public class AutorisationServiceTest {
  4. @MockBean
  5. PersonneRepository personneRepository;

Also, don't forget to add ResetMocksTestExecutionListener to prevent inter-test persistent mocks (see this issue).

答案2

得分: 1

你应该决定是要编写一个 Spring 测试还是一个 Mockito 测试。

一个 Spring 测试会加载完整的上下文,然后您可以使用 @Autowired@MockBean 进行操作:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class AutorisationServiceTest {
  3. @Autowired
  4. private IAutorisationService service;
  5. @MockBean
  6. PersonneRepository personneRepository;

一个 Mockito 测试运行速度更快,但您只会拥有通过 @InjectMocks@Mock 显式配置的对象:

  1. @RunWith(MockitoJUnitRunner.class)
  2. public class AutorisationServiceTest {
  3. @InjectMocks
  4. private IAutorisationService service;
  5. @Mock
  6. PersonneRepository personneRepository;

请注意,使用注解和专用运行器时,您永远不必使用 Mockito.mock() 来实例化模拟对象。

我猜您的 PersonneRepository 是一个 @Service、@Component 或 @Repository。因此在这里也应该使用自动装配:

  1. @Service
  2. public class AutorisationService implements IAutorisationService {
  3. @Autowired
  4. private PersonneRepository personneRepository;
英文:

You should decide whether you want to write a Spring test or a Mockito test.

A spring test will load the full context and you can then work with @Autowired and @MockBean:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class AutorisationServiceTest {
  3. @Autowired
  4. private IAutorisationService service;
  5. @MockBean
  6. PersonneRepository personneRepository;

A Mockito test runs much faster, but you will only have the objects you explicitly configured with @InjectMocks or @Mock:

  1. @RunWith(MockitoJUnitRunner.class)
  2. public class AutorisationServiceTest {
  3. @InjectMocks
  4. private IAutorisationService service;
  5. @Mock
  6. PersonneRepository personneRepository;

Note that you never have to instanciate the mock with Mockito.mock() when using annotations and specialized runners.

I guess your PersonneRepository is a @Service, @Component or @Repository. So you should use auto-wiring here as well:

  1. @Service
  2. public class AutorisationService implements IAutorisationService {
  3. @Autowired
  4. private PersonneRepository personneRepository;

答案3

得分: 0

你不能同时使用 @MockMockito.mock。请选择其中一个。

英文:

You can't use both @Mock and Mockito.mock. Choose one of them

答案4

得分: 0

在@Before的setup方法中,您需要添加MockitoAnnotations.initMocks(this)。这将注入您的模拟服务。我已经修改了下面的代码:

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class AutorisationServiceTest {
  3. @Mock
  4. PersonneRepository personneRepository;
  5. @InjectMocks
  6. private AutorisationService service;
  7. @Before
  8. public void setup() {
  9. MockitoAnnotations.initMocks(this);
  10. }
  11. @Test
  12. public void should_Find_GardeWith2Affectations() throws IOException {
  13. when(personneRepository.getAll(anyString())).thenReturn(DataLoader.mockData());
  14. service.getAll("rules");
  15. }
  16. }
  17. @Service
  18. public class AutorisationService implements IAutorisationService {
  19. private final PersonneRepository personneRepository;
  20. public AutorisationService(PersonneRepository personneRepository) {
  21. this.personneRepository = personneRepository;
  22. }
  23. @Override
  24. public List<User> getAll(String where) {
  25. return personneRepository.getAll(where));
  26. }
  27. ...
  28. }

请注意,我只翻译了您提供的代码部分。

英文:

In @Before setup method you need to add MockitoAnnotations.initMocks(this). This will inject your mocked services. I have modified the code below :

  1. @RunWith(SpringJUnit4ClassRunner.class)
  2. public class AutorisationServiceTest {
  3. @Mock
  4. PersonneRepository personneRepository;
  5. @InjectMocks
  6. private AutorisationService service;
  7. @Before
  8. public void setup() {
  9. MockitoAnnotations.initMocks(this);
  10. }
  11. @Test
  12. public void should_Find_GardeWith2Affectations() throws IOException {
  13. when(personneRepository.getAll(anyString())).thenReturn(DataLoader.mockData());
  14. service.getAll(&quot;rules&quot;);
  15. }
  16. }
  17. @Service
  18. public class AutorisationService implements IAutorisationService {
  19. private final PersonneRepository personneRepository;
  20. public AutorisationService(PersonneRepository personneRepository) {
  21. this.personneRepository = personneRepository;
  22. }
  23. @Override
  24. public List&lt;User&gt; getAll(String where) {
  25. return personneRepository.getAll(where));
  26. }
  27. ...
  28. }

huangapple
  • 本文由 发表于 2020年10月14日 23:20:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/64356509.html
匿名

发表评论

匿名网友

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

确定