2009-02-02 6 views
3

Cette question est explicite si vous savez comment utiliser JMockit: Comment puis-je me moquer d'une méthode qui a des génériques sur elle? Je veux railler cette méthode: T publique save (entité T), mais il jette toujours une exception comme ceci:Comment est-ce que je me moque d'une méthode avec des objets génériques dans JMockit?

mockit.RealMethodNotFoundForMockException: Corresponding real methods not found for the following mocks: 
Object save(Object) 
    at mockit.internal.RedefinitionEngine.modifyRealClass(RedefinitionEngine.java:130) 
    at mockit.internal.RedefinitionEngine.modifyRealClass(RedefinitionEngine.java:88) 
    at mockit.internal.RedefinitionEngine.redefineMethods(RedefinitionEngine.java:72) 
    at mockit.Mockit.setUpMocks(Mockit.java:197) 
    at com.mytest.MyTest.setUp(AdminManagerImplTest.java:83) 

Répondre

1

il fonctionne pour moi, par exemple

 
package a; 

import junit.framework.TestCase; 
import mockit.Mockit; 

public class JMockitCoreExampleTest extends TestCase { 

    public class MockMe { 
     public T save(T t) { 
      return null; 
     } 
    } 

    public void testDoOperationAbc() { 
     Mockit.redefineMethods(MockMe.class, SayThatYouMockMe.class); 
       MockMe mock = new MockMe(); 
     System.out.println(mock.save("aaa")); 
    } 

    public static class SayThatYouMockMe { 
     public T save(T t) { 
      return t; 
     } 
    } 
} 

sortie

 
Loaded external tool: mockit.integration.junit3.JUnitTestCaseDecorator 
Loaded external tool: mockit.integration.junit4.JUnit4ClassRunnerDecorator 
aaa 

peut-être que vous vous moquez de la méthode de sauvegarde d'hibernate? Si oui, essayez d'utiliser hibernate3emul.jar de jmockit

0

Je pense que votre problème ici pourrait être que votre signature de type générique ne correspond pas à celle de la méthode que vous essayez de simuler. Gardez à l'esprit que les informations de type générique ne sont pas disponibles au moment de l'exécution, donc JMockit ne voit que les méthodes qui résultent de l'effacement des informations de type générique.

Par exemple, supposons que vous avez la signature suivante:

public <T> void foo(T param) { 
    ... 
} 

Le compilateur traduit cela:

public void foo(Object param) { 
    ... 
} 

et c'est la signature qui apparaît dans le bytecode, et ce que JMockit verrait par réflexion.

En revanche, la signature suivante:

public <T extends Map> foo(T param) { 
    ... 
} 

efface à:

public void foo(Map param) { 
    ... 
} 

Donc, si, par exemple, l'implémentation simulée utilise la première signature alors que la vraie classe utilise le second, les effacements sous-jacents ne correspondraient pas, et JMockit ne serait pas capable de trouver la méthode.

Voir http://today.java.net/pub/a/today/2003/12/02/explorations.html pour plus d'infos

0

Peut-être que vous avez la même constellation que j'avais:

J'ai essayé de méthode Mock <T> T merge(T t) dans org.hibernate.ejb.EntityManagerImpl et a obtenu la même erreur Mockit.

Mockit.redefineMethods(EntityManagerImpl.class, EntityManagerImplMock.class); 

Ma faute est que la méthode de fusion non déclarée dans org.hibernate.ejb.EntityManagerImpl mais dans sa classe super AbstractEntityManagerImpl. Maintenant, j'ai

Mockit.redefineMethods(AbstractEntityManagerImpl.class, EntityManagerImplMock.class); 

avec

public static class EntityManagerImplMock { 
    public <T> T merge(final T o) { 
     // nothing 
     return o; 
    } 
} 

et tout fonctionne bien.

2

Juste pour être complet:

J'ai eu un problème similaire avec Java 1.7 en mode Java 1.6, TestNG et jMockit 1,5 et 1,16, en utilisant en méthode Mockup < ...> d'une classe.

Ma classe:

public class MyCache extends AbstractLazyCache<ExchangeObject> {...}

La méthode moquée

public abstract class AbstractLazyCache<CachedObject> extends AbstractCache { 
     // ... 

     protected void putCachedObject(String tenantId, String objectId, CachedObject o, Date expiryDate) {...} 
    } 

moqueur originale tentative:

new MockUp<MyCache>() { 
     // invoked once manually, once on expired cache 
     @Mock(invocations = 2) 
     public void putCachedObject(Invocation inv, String tenantId, String objectId, 
       RangeExchange o, Date expiryDate) { 
      // expire one second in the future 
      inv.proceed(tenantId, objectId, o, new Date(System.currentTimeMillis() + waitTimeMillis)); 
     } 
    }; 

j'ai eu une exception similaire. En ajoutant un paramètre générique supplémentaire après le public, mon cas de test a finalement réussi:

new MockUp<MyCache>() { 
     // invoked once manually, once on expired cache 
     @Mock(invocations = 2) 
     public <RangeExchange> void putCachedObject(Invocation inv, String tenantId, String objectId, 
       RangeExchange o, Date expiryDate) { 
      // expire one second in the future 
      inv.proceed(tenantId, objectId, o, new Date(System.currentTimeMillis() + waitTimeMillis)); 
     } 

    }; 
Questions connexes