Mockito: simulation d'initialisation privée sur le terrain
comment je peux simuler une variable de champ qui est initialisée en ligne?
e.g.
class Test {
private Person person = new Person();
...
public void testMethod() {
person.someMethod();
...
}
}
ici je veux me moquer personne.someMethod () en testant la méthode - Test#testMethod.
pour lequel je dois simuler l'initialisation de la variable personne. Aucun indice?
EDIT: Je ne suis pas autorisé à modifier la classe Person.
5 réponses
Mockito vient avec une classe helper pour vous sauver un peu de réflexion code de la plaque de la chaudière:
import org.mockito.internal.util.reflection.Whitebox;
//...
@Mock
private Person mockedPerson;
private Test underTest;
// ...
@Test
public void testMethod() {
Whitebox.setInternalState(underTest, "person", mockedPerson);
// ...
}
mise à Jour: Malheureusement l'équipe mockito a décidé de supprimer la classe dans Mockito 2. Donc vous êtes de retour à écrire votre propre code de boilerplate réflexion, utilisez une autre bibliothèque (par exemple Apache Commons Lang), ou tout simplement piller l' Whitebox classe (c'est sous licence MIT).
j'ai déjà trouvé la solution à ce problème dont j'ai oublié de poster ici.
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Test.class })
public class SampleTest {
@Mock
Person person;
@Test
public void testPrintName() throws Exception {
PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
Test test= new Test();
test.testMethod();
}
}
les points clés de cette solution sont:
en cours d'Exécution de mon cas de test avec PowerMockRunner:
@RunWith(PowerMockRunner.class)
demandez à Powermock de préparer
Test.class
pour la manipulation de champs privés:@PrepareForTest({ Test.class })
Et enfin en dérision le constructeur de la classe Personne:
PowerMockito.mockStatic(Person.class);
PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
assez tard à la fête, mais j'ai été frappé ici et j'ai eu l'aide d'un ami. La chose n'était pas à utiliser PowerMock. Cela fonctionne avec la dernière version de Mockito.
Mockito vient avec ça org.mockito.internal.util.reflection.FieldSetter
.
ce qu'il fait essentiellement est vous aide à modifier les champs privés en utilisant la réflexion.
C'est la façon dont vous l'utilisez -
@Mock
private Person mockedPerson;
private Test underTest;
// ...
@Test
public void testMethod() {
FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person", mockedPerson);
// ...
verify(mockedPerson).someMethod()
}
de cette façon, vous pouvez passer un objet simulé et ensuite le vérifier tard.
Référence:
https://www.codota.com/code/java/methods/org.mockito.internal.util.reflection.FieldSetter/set
peut être de plusieurs façons, L'une d'elles peut être
Class Test {
private Person person = new Person();
...
public void testMethod() {
person.someMethod();
...
}
}
Ce doit être modifié comme
Class Test {
private Person person;
public Test() {
if(person == null) {
person = new Person();
}
}
...
public void testMethod() {
person.someMethod();
...
}
}
Dans votre test,
@Runwith(SpringJunit4Runner.class)
public class TestingTest {
@InjectMocks
Test test;
@Mock
private Person person;
@Before
public void setUp() {
when(person.XXX).thenReturn("");
}
@Test
public void testMethod() {
...........
}
}
le code suivant peut être utilisé pour initialiser mapper dans REST client mock. mapper
le champ est privé et doit être réglé lors de la configuration d'essai de l'unité.
import org.mockito.internal.util.reflection.FieldSetter;
new FieldSetter(client, Client.class.getDeclaredField("mapper")).set(new Mapper());