2013-09-05 3 views
10

Ich habe ein EncouragementService.groovy mit Verfahren folgendenWie Grails Service mit Spock testen?

class EncouragementService { 
    def stripePaymentService 

    def encourageUsers(List<User> users){ 
    if(null != users && users.size()>0){ 
     for(User user : users){ 
     //logic 
     stripePaymentService.encourage(user) 
     // 
     } 
    } 
    } 
    } 

obigen Code in JAVA Universum zu testen, mit JUnit Ich würde zwei oder drei Benutzer in Setup zuerst erstellen. Übergeben Sie die Liste der Benutzer an encourageUsers(...) Methode und überprüfen Sie, was ich will mit dem Ergebnis.

Wie kann ich die gleiche Sache hier in Grails erreichen,

import com.github.jmkgreen.morphia.Datastore; 

@TestFor(EncouragementService) 
class EncouragementServiceSpec { 

    def morphiaService = new MorphiaService() 

    void testEncourageUsers() { 
     List<User> users = createUsers(); 
     encouragementService.(users) 
      // 
    } 

    def createUsers(){ 
     Datastore datastore = morphiaService.dataStoreInstance() 
     def user = new User() 
     user.setName("Prayag Upd") 
     // 
     datastore.save(user) 
     [user] 
    } 
} 

Ich bin mit spock:0.7

plugins { 
    test(":spock:0.7") { exclude "spock-grails-support" } 
} 

Antwort

13

Service-Klasse kann wie folgt optimiert werden
Spock Tests ganz andere Ebene, wo Sie das Verhalten (hält sich an BDD) testen. Die Test-Klasse würde wie folgt aussehen:

import spock.lang.* 

@TestFor(EncouragementService) 
@Mock(User) //If you are accessing User domain object. 
class EncouragementServiceSpec extends Specification{ 
    //def encouragementService //DO NOT NEED: mocked in @TestFor annotation 

    void "test Encourage Users are properly handled"() { 
     given: "List of Users" 
      List<User> users = createUsers() 

     when: "service is called" 
      //"service" represents the grails service you are testing for 
      service.encourageUsers(users) 

     then: "Expect something to happen" 
      //Assertion goes here 
    } 

    private def createUsers(){ 
     return users //List<User> 
    } 
} 
+0

"Patience" ist [mein Name] (http://www.ask.com/question/what-is-the-meaning-of-the-name-dhiraj), ich mache keine Witze;). Ehrlich gesagt, ich hatte kürzlich eine [Präsentation] (http://dmahapatro.github.io/bdd-grails-spock-presentation/#/) auf Spock in der lokalen Grails-Benutzergruppe, also dachte ich, ich würde mit etwas prahlen, was ich gearbeitet habe auf. ;) @ SérgioMichels – dmahapatro

+0

@dmahapatro Wenn 'User' keine' grails-app/domain' basierte Entität ist, bekomme ich 'Failure: test Benutzer werden richtig behandelt (np.zazzercode.service.EncouragementServiceSpec) | org.codehouse.groovy.grails.exceptions.GrailsConfigurationException: Domain-Klasse [Klasse np.zazzercode.domain.User] kann nicht hinzugefügt werden. Es ist keine Domain! \t bei grails.test.mixin.domain.DomainClassUnitTestMixin.registerGrailsDomainClass: gemeint (DomainClassUnitTestMixin.groovy 209) ' – prayagupd

+0

@PrayagUpd Ja, wenn Benutzer nicht ein Domäne-Klasse ist, dann müssen Sie nicht' @ Mock' das, was ich ist in der Antwort. – dmahapatro

4

Verwenden Sie die build-test-data plugin die Benutzer zu bauen.

@TestFor(EncouragementService) 
@Build(User) 
class EncouragementServiceSpec extends Specification { 

    def "encourage users does x"() { 
    given: 
    def users = createUsers(); 

    when: 
    service.encourageUsers(users) 

    then: 
    // assert something 
    } 

    def createUsers(){ 
    [User.build(), User.build(), User.build()] 
    } 
} 

Ich habe auch ein paar Änderungen am Code vorgenommen, um es zu einer richtigen Spock-Spezifikation zu machen. Ihr Test muss die Spezifikation erweitern und Sie möchten sich vielleicht mit Spock's keywords vertraut machen.

class EncouragementService { 
    def encourageUsers(List<User> users){ 
     if(users){ //Groovy truth takes care of all the checks 
      for(user in users){ 
      //logic 
      } 
     } 
    } 
} 

Spock Unit Test:

+0

[build-Test-Daten-Plugin] (https://github.com/tednaleid/build-test-data) sieht genial, aber scheint nicht für nicht arbeiten 'grails-app/domain' basierte Entitäten. Überschreibt Ausnahme 'org.codehouse.groovy.grails.exceptions.GrailsConfigurationException: Domänenklasse [Klasse np.zazzercode.domain.User] kann nicht hinzugefügt werden. Es ist keine Domain' – prayagupd

+0

Ja, es funktioniert nur für Domain-Klassen. – Nicholas