2017-02-17 5 views
1

Ich habe so etwas wie dies:Wie spotze ich eine Implementierungsklasse?

public interface SomeInterface { 
    public String someMethod(String someArg1, String someArg2); 
} 

public class SomeInterfaceImpl { 

    @Override 
    public String someMethod(String someArg1, String someArg2) { 
     String response; 

     // a REST API call which fetches response (need to mock this) 

     return response; 
    } 
} 

public class SomeClass { 

    public int execute() { 

     int returnValue; 

     // some code 

     SomeInterface someInterface = new SomeInterfaceImpl(); 
     String response = someInterface.someMethod("some1", "some2"); 

     // some code 

     return returnValue; 
    } 
} 

ich die execute() Methode in SomeClass mit JUnit testen möchten. Da someMethod(String someArg1, String someArg2) eine REST-API aufruft, möchte ich someMethod vortäuschen, um eine vordefinierte Antwort zurückzugeben. Aber irgendwie wird der echte someMethod aufgerufen, anstatt die vordefinierte Antwort zurückzugeben. Wie kann ich es funktionieren lassen?

Hier ist, was ich versucht habe, mit Mockito und PowerMockito:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ SomeInterface.class, SomeInterfaceImpl.class, SomeClass.class }) 
public class SomeClassTest { 

    @Test 
    public void testExecute() { 
     String predefinedResponse = "Some predefined response"; 
     int expectedReturnValue = 10; 

     SomeInterfaceImpl impl = PowerMockito.mock(SomeInterfaceImpl.class); 
     PowerMockito.whenNew(SomeInterfaceImpl.class).withAnyArguments().thenReturn(impl); 
     PowerMockito.when(impl.someMethod(Mockito.any(), Mockito.any())).thenReturn(predefinedResponse); 

     SomeClass someClass = new SomeClass(); 
     int actualReturnValue = someClass.execute(); 
     assertEquals(expectedReturnValue, actualReturnValue); 
     } 
} 
+0

Verwandte? http://stackoverflow.com/questions/25317804/using-powermockito-whnew-is-not-getting-mocked-and-original-method-is- –

+4

Dies ist * genau * wo Abhängigkeit Injektion kommt. Do not Verwenden Sie 'new', übergeben Sie' SomeInterface' als Parameter. – chrylis

+0

@AndyTurner Ich habe 'SomeInterface interface = PowerMockito.mock (SomeInterface.class)', gefolgt von 'PowerMockito.when (interface.someMethod (Mockito.any(), Mockito.any())). ThenReturn (vordefinierteResponse);' . Es ergab sich das gleiche Problem. – user87407

Antwort

1

Sie müssen das nicht tun.

Sie ändern Ihre zu testende Methode, um NOT neu direkt anzurufen.

Stattdessen verwenden Sie beispielsweise die Abhängigkeitsinjektion.

Ja, das könnte mit Powermock gemacht werden, aber bitte glauben Sie mir: das ist der falsche Ansatz! Hier

+0

Bedeutet das, muss ich Spring-Unterstützung für die Abhängigkeitsinjektion hinzufügen, oder wahrscheinlich einen Setter für 'SomeInterfaceImpl' hinzufügen? Ich fürchte, ich darf den Code nicht umgestalten. Könnten Sie zeigen, wie es mit PowerMock gemacht werden kann? – user87407

+2

Dependency-Injection bedeutet nicht, ein DI-Framework zu verwenden: es bedeutet nur, dass Sie Abhängigkeiten in die Instanz übergeben, irgendwie - Konstruktorparameter, Setter, DI-Framework ... –

+0

Außerdem hat 'SomeInterface' mehrere Implementierungen, die in verschiedenen Klassen wie' 'verwendet werden SomeClass'. Welche Klasse zu verwenden ist, wird zur Laufzeit auf der Basis eines bestimmten Kriteriums entschieden, instanziiert durch Reflexion und ihre Ausführungsmethode wird aufgerufen. Es wird also nicht möglich sein, die Implementierung von 'SomeInterface' zu ​​setzen oder sie im Konstruktor zu übergeben. – user87407

3

ist ein Beispiel für die Injektion Abhängigkeiten ohne Rahmen:

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.InjectMocks; 
import org.mockito.Mock; 
import org.mockito.runners.MockitoJUnitRunner; 

import static org.junit.Assert.assertEquals; 
import static org.mockito.Matchers.anyString; 
import static org.mockito.Mockito.when; 

interface SomeInterface { 
    String someMethod(String someArg1, String someArg2); 
} 

class SomeInterfaceImpl implements SomeInterface { 

    @Override 
    public String someMethod(String someArg1, String someArg2) { 
    String response; 

    response = "the answer.";// a REST API call which fetches response (need to mock this) 

    return response; 
    } 
} 

class SomeClass { 
    private final SomeInterface someInterface; 

    SomeClass(final SomeInterface someInterface) { 
    this.someInterface = someInterface; 
    } 

    public SomeClass() { 
    this(new SomeInterfaceImpl()); 
    } 

    public int execute() { 

    int returnValue; 

    // some code 

    String response = someInterface.someMethod("some1", "some2"); 

    returnValue = 42; // some code 

    return returnValue; 
    } 
} 

@RunWith(MockitoJUnitRunner.class) 
class SomeClassTest { 
    private static final String SOME_PREDEFINED_RESPONSE = "Some predefined response"; 
    @Mock 
    private SomeInterface someInterface; 
    @InjectMocks 
    private SomeClass underTest; 

    @Before 
    public void setup() { 
    when(someInterface.someMethod(anyString(), anyString())).thenReturn(SOME_PREDEFINED_RESPONSE); 
    } 

    @Test 
    public void testExecute() { 
    int expectedReturnValue = 42; 
    int actualReturnValue = underTest.execute(); 
    assertEquals(expectedReturnValue, actualReturnValue); 
    } 
} 
+0

Nein, hat nicht funktioniert. Gleiches Problem. – user87407

+0

Wenn Sie mir zeigen, was Sie versucht haben, werde ich Ihnen gerne helfen. – Andreas

Verwandte Themen