2016-03-23 22 views
25

Come posso prendere in giro una variabile di campo che viene inizializzata in linea?Mockito: inizializzazione del campo privato fittizio

ad es.

class Test { 
    private Person person = new Person(); 
    ... 
    public void testMethod() { 
     person.someMethod(); 
     ... 
    } 
} 

qui voglio prendere in giro person.someMethod() mentre il metodo di prova - Test # testMethod.

per cui ho bisogno di simulare l'inizializzazione della variabile persona. Qualche indizio?

MODIFICA: Non sono autorizzato a modificare la classe Persona.

+0

Questo link potrebbe essere utile a voi http://stackoverflow.com/questions/13645571/how-to-mock-a-private-dao-variable – Popeye

+2

Si dovrebbe refactoring del codice in modo da poter passare un simulato a 'Persona'. Le opzioni includono l'aggiunta di un costruttore per farlo o l'aggiunta di un metodo setter. –

risposta

9

Ho già trovato la soluzione a questo problema che ho dimenticato di postare qui.

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ Test.class }) 
public class SampleTest { 

@Mock 
Person person; 

@Test 
public void testPrintName() throws Exception { 
    PowerMockito.mockStatic(Person.class); 
    PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person); 
    Test test= new Test(); 
    test.testMethod(); 
    } 
} 

punti chiave di questa soluzione sono:

  1. Esecuzione miei casi di test con PowerMockRunner: @RunWith(PowerMockRunner.class)

  2. Istruire Powermock per preparare Test.class per la manipolazione dei campi privati: @PrepareForTest({ Test.class })

  3. E infine simulare il costruttore per la classe Person:

    PowerMockito.mockStatic(Person.class); PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);

0

possono essere molti modi, uno di essi possono essere

Class Test { 
    private Person person = new Person(); 
    ... 
    public void testMethod() { 
    person.someMethod(); 
    ... 
    } 
} 

Questo deve essere modificato come

Class Test { 
    private Person person; 
    public Test() { 
     if(person == null) { 
     person = new Person(); 
     } 
    } 
    ... 
    public void testMethod() { 
    person.someMethod(); 
    ... 
    } 

} 

nel test di prova,

@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() { 

........... 
} 
} 
+0

Non sono sicuro che funzionerà in questo modo, non possiamo prendere in giro il costruttore nel modo che stai facendo. usando Powermock, possiamo farlo. Ma a parte questo non ho il permesso di modificare questa classe di persone. :( – Arun

37

Mockito viene fornito con una classe di supporto per salvarti un po 'di riflessione Codice piastra di riscaldamento:

import org.mockito.internal.util.reflection.Whitebox; 

//... 

@Mock 
private Person mockedPerson; 
private Test underTest; 

// ... 

@Test 
public void testMethod() { 
    Whitebox.setInternalState(underTest, "person", mockedPerson); 
    // ... 
} 

Aggiornamento: Purtroppo la squadra ha deciso di Mockito remove the class in Mockito 2. Quindi si torna a scrivere il proprio codice riflesso boilerplate, utilizzare un'altra libreria (per esempio Apache Commons Lang), o semplicemente rubare la classe WhiteboxMIT licensed).

+0

Sto spiando il mio oggetto target per altri motivi e in questo caso quando il mio oggetto è spia, non posso impostare lo stato interno in questo modo: – Arun

+0

Perché no? Lo sto usando con le spie.Interrompi tutto ciò che è necessario eseguire lo stub, quindi impostalo sull'istanza di Test. – Ralf

+0

Attenzione: Whitebox si trova nel pacchetto 'internal' e non sembra funzionare più su Mockito 2.6.2. – Nova

Problemi correlati