2016-03-23 10 views
25

Wie kann ich eine Feldvariable spotten, die inline initialisiert wird?Mockito: Mock private Feld Initialisierung

z.B.

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

Hier möchte ich person.someMethod() während Testverfahren verspotten - Test # testmethod.

für die ich die Initialisierung der Person Variable verspotten muss. Irgendeine Ahnung?

EDIT: Ich bin nicht berechtigt, Personenklasse zu ändern.

+0

Dieser Link könnte für Sie hilfreich http://stackoverflow.com/questions/13645571/how-to-mock-a-private-dao-variable – Popeye

+2

Sie sollten Ihre Refactoring Code, so dass Sie einen Schein für "Person" eingeben können. Zu den Optionen gehören das Hinzufügen eines Konstruktors oder das Hinzufügen einer Setter-Methode. –

Antwort

9

Ich habe bereits die Lösung für dieses Problem gefunden, das ich hier vergessen habe.

@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(); 
    } 
} 

Kernpunkte zu dieser Lösung sind:

  1. mit PowerMockRunner meine Testfälle laufen: @RunWith(PowerMockRunner.class)

  2. Instruct PowerMock Test.class zur Manipulation von privaten Felder vorzubereiten: @PrepareForTest({ Test.class })

  3. Und schließlich spotten Sie den Konstruktor für die Klasse Person:

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

0

Mai viele Möglichkeiten sein, Einer von ihnen

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

als

modifiziert werden Dies muss sein
Class Test { 
    private Person person; 
    public Test() { 
     if(person == null) { 
     person = new Person(); 
     } 
    } 
    ... 
    public void testMethod() { 
    person.someMethod(); 
    ... 
    } 

} 

In Ihrem Test 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() { 

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

Ich bin mir nicht sicher, ob es so funktioniert, wir können den Konstruktor nicht so darstellen, wie Sie es tun. Mit Powermock können wir das machen. Aber abgesehen davon darf ich diese Personenklasse nicht ändern. :( – Arun

37

Mockito kommt mit eine helfer-klasse, um dir ein paar reflexionen zu sparen kesselplatte code:

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

//... 

@Mock 
private Person mockedPerson; 
private Test underTest; 

// ... 

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

Update: Leider ist das Mockito Team entschieden remove the class in Mockito 2. Also sind Sie wieder Ihren eigenen Reflexion vorformulierten Code zu schreiben, eine andere Bibliothek verwenden (z Apache Commons Lang), oder einfach die Whitebox Klasse enteignen (es ist MIT licensed).

+0

Ich spioniere mein Zielobjekt aus anderen Gründen und in diesem Fall, wenn mein Objekt Spion ist, kann ich den internen Zustand auf diese Weise nicht setzen. – Arun

+0

Warum nicht? Ich benutze es mit Spionen. Erzeuge eine Person-Instanz.Stub, was Stubbing benötigt, und setze es dann auf deine Testinstanz. – Ralf

+0

Warnung: Whitebox ist im 'internen' Paket und scheint auf Mockito 2.6.2 nicht mehr zu funktionieren. – Nova

Verwandte Themen