2015-03-18 1 views
0

J'ai un test unitaire qui échoue car il appelle indirectement une méthode qui dépend d'un service. Mais lorsque les tests unitaires sont exécutés, le service est hors ligne. J'ai essayé d'utiliser Mockito pour se moquer du comportement de cette méthode dépendante du service, mais le problème est que cette méthode est une méthode statique dans une classe finale, donc Mockito ne fonctionne pas dans ce cas.Le test de l'unité échoue car le service est hors ligne

J'ai également essayé d'utiliser PowerMock avec Mockito, mais encore une fois que la méthode n'est pas appelée directement à partir du test unitaire, cela ne fonctionne pas. Ceci est le squelette de mon test unitaire:

@RunWith(PowerMockRunner.class) 
@PrepareForTest(FinalClassWithStaticMethod.class) 
public class MyObjTestCase { 
    @Test public void myRandomTest() throws Exception { 
     PowerMockito.mockStatic(FinalClassWithStaticMethod.class); 
     MyObj returnObj = new MyObj(); 
     // setup fields for returnObj 
     ... 
     ... 
     PowerMockito.when(FinalClassWithStaticMethod.staticMethod((AnotherObj)anyObject())).thenReturn(returnObj); 
     AnotherObj obj = new AnotherObj(); 
     // setup fields for obj... 

     MyObj mockedObj =  FinalClassWithStaticMethod.staticMethod(obj); // This returns the mocked value. 
     // TestUtil.staticMethod calls another class' method which calls FinalClassWithStaticMethod.staticMethod. 
     MyObj myObj = TestUtil.staticMethod(obj); // This does not return mocked value. 
    } 
} 

Mes questions:

sont les tests unitaires destinés à même de tels scénarios?

Existe-t-il un moyen par lequel je peux faire fonctionner ce test unitaire sans modifier la classe finale? Dans le cas où je dois modifier les classes existantes, quelle est la bonne façon de le faire par des effets minimes sur le code dépendant? Bien que ce soit un scénario spécifique, les liens vers des exemples qui présentent un tel refactoring seront d'une grande aide.

Répondre

0

Dans votre cas, vous devriez idéalement vous moquer de l'objet de service. La simulation ne fonctionnera que si la méthode qui appelle le service utilise l'objet mocké. Si le client du service peut être créé et transmis à la classe appelant le service directement à partir du test unitaire (setter/constructeur) lorsque l'objet est créé dans le test unitaire, alors vous n'avez pas besoin de faire trop de changements.

Exemple de code:

class CallsService { 
    public CallsService(final ServiceClient client) { 
    ... } 
    public someMethod() { 
     client.callService(); 
    } 
} 

En test unitaire:

void test() { 
    ServiceClient mockedClient = mock(ServiceClient.class); 
    // Setup mocks to return as required 
    CallsService caller = new CallsService(mockedClient); 
} 

De cette façon, l'appelant utilisera le mockedClient dans le test unitaire, et dans le programme réel, il peut obtenir un client au vrai service.