J'ai une classe de service avec 3 méthodes, la classe de service utilise également des annotations @Autowired. Sur 3 méthodes, je veux me moquer de deux méthodes mais utiliser la vraie méthode pour la 3ème.
Le problème est:
Je connais ces deux options:
@Autowired
@InjectMocks
private ProductController productController;
@SpyBean
private ProductService productServiceSpy;
@Autowired
private ProductController productController;
@Autowired
private ProductService productService;
@Before
public void setUp() {
ProductService productServiceSpy = Mockito.spy(productService);
ReflectionTestUtils.setField(productController, "productService", productServiceSpy);
}
J'ai été moi-même surpris, mais cela fonctionne pour nous. Nous avons beaucoup d'endroits comme:
@Spy
@Autowired
private FeatureService featureService;
Je pense que je sais pourquoi vous êtes confronté à ce problème. Il ne s'agit pas d'injection, il s'agit de when(bloMock.doSomeStuff()).thenReturn(1)
vs doReturn(1).when(bloMock).doSomeStuff()
. Voir: http://www.stevenschwenke.de/spyingWithMockito
La différence très importante est que la première option appellera en fait la méthode doSomeStuff () - tandis que la seconde ne le fera pas. Les deux entraîneront doSomeStuff () pour retourner le 1 souhaité.
En utilisant @Spy
ensemble avec @Autowired
fonctionne jusqu'à ce que vous souhaitiez vérifier l'interaction entre cet espion et un composant différent dans lequel cet espion est injecté. Ce que j'ai trouvé pour travailler était l'approche suivante trouvée sur https://dzone.com/articles/how-to-mock-spring-bean-version-2
@Configuration
public class AddressServiceTestConfiguration {
@Bean
@Primary
public AddressService addressServiceSpy(AddressService addressService) {
return Mockito.spy(addressService);
}
}
Cela transforme votre composant câblé automatiquement en un objet espion, qui sera utilisé par votre service et pourra être vérifié dans vos tests.