2016-07-15 9 views
0

Ich habe eine Methode in meinem MainActivity (Android) und ich möchte verspotten die A Instanz verspotten:wie mit Mockito

public void some_method() { 
    A a = new A(); 
    .... 
} 

so habe ich eine Art von Factory-Klasse als solche

public class SomeFactory(){ 

// some constructor 
public A populateWithParameter(Parameter parameter){ 
return new A(parameter) 
} 
} 

und das Verfahren, das oben verwandelt sich in

public void some_method(SomeFactory someFactory) { 
     A a = someFactory.populateWithParameter(parameter); 
     a.method_call()   
     .... 
    } 

I diese

01 versucht
@Mock 
    SomeFactory someFactory; 

public void testSomeMethod() throws Exception { 
     SomeFactory someFactory = new SomeFactory(); 
     when(someFactory.populateWithParameter(
       some_parameter)).thenReturn(null); 

     mainActivity.some_method(someFactory); 
... 
    } 

aber ich bekomme diese Fehlermeldung

org.mockito.exceptions.misusing.MissingMethodInvocationException: 
when() requires an argument which has to be 'a method call on a mock'. 
For example: 
when(mock.getArticles()).thenReturn(articles); 

Antwort

1

Sie Ihre Fabrik nicht verspotten. Falscher Methodenaufruf.

Tun Sie dies stattdessen.

SomeFactory someFactory = mock(SomeFactory.class) 
    when(someFactory.populateWithParameter(
      some_parameter)).thenReturn(null); 

    mainActivity.some_method(someFactory); 

UPDATE

Ihr Code geändert hat, so auf Vollständigkeit das ist, was Ihr Test aussehen sollte. In dem aktualisierten Code überschreiben Sie Ihre mock mit einem realen Objekt. Angenommen, Ihre Objekte sind korrekt eingerichtet. Beachten Sie die unterschiedliche Syntax für die Bereitstellung eines Rückgabeobjekts. Ich denke, das ist lesbarer.

@Mock SomeFactory mockFactory; 

@Before 
public void setUp() { 
    MockitoAnnotations.initMocks(this); // set up annotated mocks 
} 

@Test 
public void testSomeMethod() { 
    A subject = new A(); 
    doReturn(subject).when(mockFactory) 
         .populateWithParameter(any(Parameter.class)); 
    main_activity.some_method(mockFactory); 
    verify(mockFactory,times(1)).populateWithParameter(any(Parameter.class)); 
} 

Best Practices

  • Wenn Methoden und Variablen zu benennen, verwenden Sie camelcase. So wird main_activity wird MainActivity, some_method wird SomeMethod.
+0

Vielen Dank für Ihre Antwort. In der Tat habe ich 'thenReturn (null)' nur um es einfach zu machen, aber ich brauche etwas wie 'thenReturn (new A)'. Also, wenn ich das tue, bekomme ich ein Problem, weil nach dem Erstellen des Objekts 'A a', ein Methodenaufruf' a.method_call() ', aber dann bekomme ich' java.lang.NullPointerException: Versuch, virtuelle Methode aufzurufen " some.package.method_call "für eine Nullobjektreferenz". Hast du eine Idee, wie das zu beheben ist? – user1611830

+0

Also in Ihrer A-Klasse gibt es einen Aufruf von method_call? Ich müsste diesen Code auch sehen. – StuStirling

+0

sicher, ich habe gerade meinen Code bearbeitet! – user1611830

0

Sie müssen die Instanz A aus Ihrem Test überschreiben. In der Regel wird dazu ein Injection-Framework verwendet. Für einen einfachen Fall können Sie das zu testende Feld protected erstellen (vorausgesetzt, die Testklasse befindet sich im selben Paket wie die zu testende Klasse).

Der Fehler, den Sie sehen, interagiert mit einem "echten" Objekt, als wäre es ein Mock.

In diesem Fall SomeFactory ein reales Objekt ist, damit es nicht when()ed

0

Aus der Sicht der Antwort von @ DiscoS2 sein kann, ist es in der Tat ein Problem mit dieser Erklärung sollten

MockitoAnnotations.initMocks(this); 

Sie verwenden stattdessen SomeFactory someFactory = mock(SomeFactory.class) und dann folgen Sie der aktualisierten Antwort von @ DiscoS2