Quelle est la différence entre @Mock
et @InjectMocks
dans le framework Mockito?
java
unit-testing
mocking
mockito
user2249972
la source
la source
Réponses:
@Mock
crée une maquette.@InjectMocks
crée une instance de la classe et injecte les simulations qui sont créées avec les annotations@Mock
(ou@Spy
) dans cette instance.Notez que vous devez utiliser
@RunWith(MockitoJUnitRunner.class)
ouMockito.initMocks(this)
pour initialiser ces mocks et les injecter.la source
Il s'agit d'un exemple de code expliquant comment
@Mock
et@InjectMocks
fonctionne.Disons que nous avons
Game
etPlayer
classe.Comme vous le voyez, la
Game
classe a besoinPlayer
effectuer unattack
.Mockito se moquera d'une classe Player et son comportement en utilisant
when
etthenReturn
méthode. Enfin, l'utilisation de@InjectMocks
Mockito mettra celaPlayer
en placeGame
.Notez que vous n'avez même pas besoin de créer un
new Game
objet. Mockito l'injectera pour vous.Nous obtiendrons également le même comportement en utilisant
@Spy
annotation. Même si le nom de l'attribut est différent.C'est parce que Mockito vérifiera la
Type Signature
classe de jeu, qui estPlayer
etList<String>
.la source
Dans votre classe de test, la classe testée doit être annotée avec
@InjectMocks
. Cela indique à Mockito dans quelle classe injecter les mocks:À partir de là, nous pouvons spécifier quelles méthodes ou objets spécifiques à l'intérieur de la classe, dans ce cas
SomeManager
, seront remplacés par des mocks:Dans cet exemple, l'
SomeDependency
intérieur de laSomeManager
classe sera moqué.la source
@Mock
l'annotation se moque de l'objet concerné.@InjectMocks
l'annotation permet d'injecter dans l'objet sous-jacent les différents (et pertinents) mocks créés par@Mock
.Les deux sont complémentaires.
la source
@InjectMocks
pour construire cette classe et l'espionner aussi.Par exemple
Ici, nous avons besoin de la classe DAO pour la classe de service. Donc, nous nous en moquons et l'injectons dans l'instance de classe de service. De même, dans le framework Spring, tous les beans @Autowired peuvent être moqués par @Mock dans jUnits et injectés dans votre bean via @InjectMocks.
MockitoAnnotations.initMocks(this)
La méthode initialise ces simulations et les injecte pour chaque méthode de test, elle doit donc être appelée dans lasetUp()
méthode.Ce lien a un bon tutoriel pour le framework Mockito
la source
Un "framework de simulation", sur lequel Mockito est basé, est un framework qui vous donne la possibilité de créer des objets de simulation (en termes anciens, ces objets pourraient être appelés shunts, car ils fonctionnent comme des shunts pour la fonctionnalité dépendante) En d'autres termes, une simulation est utilisé pour imiter l'objet réel dont dépend votre code, vous créez un objet proxy avec le framework de simulation. En utilisant des objets fictifs dans vos tests, vous passez essentiellement des tests unitaires normaux aux tests d'intégration
Mockito est un framework de test open source pour Java publié sous la licence MIT, c'est un "framework de simulation", qui vous permet d'écrire de beaux tests avec une API propre et simple. Il existe de nombreux cadres de simulation différents dans l'espace Java, mais il existe essentiellement deux types principaux de cadres d'objets fictifs, ceux qui sont implémentés via un proxy et ceux qui sont implémentés via le remappage de classe.
Les frameworks d'injection de dépendances comme Spring vous permettent d'injecter vos objets proxy sans modifier aucun code, l'objet simulé attend qu'une certaine méthode soit appelée et il retournera un résultat attendu.
L'
@InjectMocks
annotation tente d'instancier l'instance de l'objet de test et injecte des champs annotés avec@Mock
ou@Spy
dans des champs privés de l'objet de test.MockitoAnnotations.initMocks(this)
, réinitialise l'objet de test et réinitialise les mocks, alors n'oubliez pas de l'avoir à votre@Before
/@BeforeMethod
annotation.la source
Un avantage que vous obtenez avec l'approche mentionnée par @Tom est que vous n'avez pas besoin de créer de constructeurs dans SomeManager, et donc de limiter les clients pour l'instancier.
Que ce soit une bonne pratique ou non dépend de la conception de votre application.
la source
Beaucoup de gens ont donné une bonne explication ici au sujet
@Mock
vs@InjectMocks
. J'aime ça, mais je pense que nos tests et notre application doivent être écrits de telle manière que nous ne devrions pas avoir besoin d'utiliser@InjectMocks
.Référence pour une lecture plus approfondie avec des exemples: https://tedvinke.wordpress.com/2014/02/13/mockito-why-you-should-not-use-injectmocks-annotation-to-autowire-fields/
la source
@Mock
est utilisé pour déclarer / simuler les références des beans dépendants, tandis que@InjectMocks
est utilisé pour simuler le bean pour lequel le test est en cours de création.Par exemple:
test pour la classe
A
:la source
L'annotation @InjectMocks peut être utilisée pour injecter automatiquement des champs fictifs dans un objet de test.
Dans l'exemple ci-dessous, @InjectMocks a utilisé pour injecter le mock dataMap dans la dataLibrary.
la source
Notez que ces éléments
@InjectMocks
sont sur le point d'être obsolèteset vous pouvez suivre la réponse et le lien @avp sur:
la source
Bien que les réponses ci-dessus aient couvert, j'ai juste essayé d'ajouter des détails minutieux que je vois manquants. La raison derrière eux (Le pourquoi).
Illustration:
Référence
la source