2010-10-30 16 views
10

ont un objet de domaine Grails qui a une fonction statique sur mesure pour saisir les données de la base de donnéesComment simulez-vous une méthode statique d'un objet de domaine dans Grails?

class Foo { 
    /* member variables, mapping, constraints, etc. */ 

    static findByCustomCriteria(someParameter, List listParameter) { 
     /* code to get stuff from the database... */ 

     /* 
      Return value is a map 
      ["one": "uno", "two": "due", "three": "tre"] 
     */ 
    } 

} 

La fonction statique findByCustomCriteria utilise createCriteria() pour construire la requête qui extrait des données de la table Foo, ce qui signifie mockDomain(Foo) ne fonctionne pas correctement lors des tests unitaires. Ce que j'essaie de faire pour contourner ce problème, c'est d'utiliser l'une des méthodes générales de moquerie pour se moquer de findByCustomCriteria, mais je ne peux pas obtenir la syntaxe tout à fait raison.

J'ai un contrôleur BarController que j'essaie de tester, et enterré dans l'appel à BarController.someFunction() il y a un appel à Foo.findByCustomCriteria().

class BarControllerTest extends ControllerUnitTestCase { 

    protected void setUp() { 
     super.setUp() 
    } 

    protected void tearDown() { 
     super.tearDown() 
    } 

    void testSomeFunction() { 

     /* Mocking for Foo goes here */ 

     assertEquals("someValue", controller.someFunction()) 
    } 
} 

Qu'est-ce qui serait un moyen de se moquer de cela?

J'ai essayé d'utiliser new MockFor(), mockFor() et metaClass, mais je n'arrive pas à le faire fonctionner.


Edit:

Chaque fois que j'essayé de se moquer de ceci, j'ai essayé de se moquer comme si ...

Foo.metaClass.'static'.findByCustomCriteria = { someParam, anotherParam -> 
    ["one": "uno", "two": "due", "three": "tre"] 
} 

Je suppose que je ne mentionnaient pas assez d'informations au départ.

+0

mettre les trucs moqueur et foo dans ... c'est ce que nous devons voir pour aider – hvgotcodes

Répondre

14

Je l'ai rencontré ce scénario plus d'une fois, vous devez modifier le statique MetaClass de Foo:

Foo.metaClass.'static'.findByCustomCriteria = { someParameter, List listParameter -> 
    ["one": "uno", "two": "due", "three": "tre"] 
} 

En général, je vais le mettre dans la configuration de test, donc je ne pas oublier quand il doit être appliqué.

+0

Cette solution ne fonctionne pas. Je suis en train de mettre à jour la question en conséquence. – haydenmuhl

+0

@haydenmuhl: J'ai mis à jour la solution pour inclure un argument explicite (j'avais supposé que le paramètre implicite it serait suffisant, mais peut-être pas, ce qui pourrait être le problème (c'est-à-dire la signature de surcharge de méthode)). Veuillez réessayer. –

+0

Votre solution aurait probablement fonctionné, mais je n'ai pas inclus les bonnes informations dans ma question. La signature de la méthode que j'utilisais était erronée. En fait, il fallait un objet et une liste, et je me moquais de deux objets. Je vais mettre à jour la question. Si vous mettez à jour votre réponse, je la sélectionnerai comme correcte. – haydenmuhl

4

En Grails 2.0 et plus, vous pouvez utiliser la classe GrailsMock comme celui-ci

def mockControl = new GrailsMock(MyDomainClass) 
mockControl.demand.static.get() {id -> return null} // Static method 
... 
mockControl.verify() 

Voir here.