2009-07-11 16 views
1

Unit testing Abstract classes in GroovymockForConstraintsTests abstrakte groovy Klasse

fragte ich eine Frage vorherige über Unit-Tests und eine Domain-Klasse verspotten, aber ich glaube nicht, dass ich spezifisch genug war. Ich habe eine Domain-Klasse:

package toplevel.domain 

abstract class Party { 
    static hasMany = [roles:PartyRole] 
    static constraints = { 
     roles(nullable:true) 
     dateCreated(display:false) 
     lastUpdated(display:false) 
    } 
    List roles 
    Date dateCreated 
    Date lastUpdated 
} 

Hier ist mein Unit-Test:

import grails.test.* 
import toplevel.domain.* 

class PartyTests extends GrailsUnitTestCase { 
    Party party 
    protected void setUp() { 
     super.setUp() 
     party = [:] as Party 
     mockForConstraintsTests(Party, [party]) 
    } 

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

    void testNullRolesIsValid() { 
     party.roles = null 
     assertTrue "The roles should be nullable", party.validate() 
    } 
} 

Hier sind die Testergebnisse: kann nicht eine neue Instanz der Klasse erstellen [toplevel.domain.Party]!

org.codehaus.groovy.grails.exceptions.NewInstanceCreationException: kann nicht eine neue Instanz der Klasse [toplevel.domain.Party] erstellt! bei grails.test.MockUtils.prepareForConstraintsTests (MockUtils.groovy: 540) bei grails.test.MockUtils $ prepareForConstraintsTests.call (Unbekannt Quelle) bei grails.test.GrailsUnitTestCase.mockForConstraintsTests (GrailsUnitTestCase.groovy: 111) bei PartyTests.setUp (PartyTests.groovy: 9) bei _GrailsTest_groovy $ _run_closure4.doCall (_GrailsTest_groovy: 203) bei _GrailsTest_groovy $ _run_closure4.call (_GrailsTest_groovy) bei _GrailsTest_groovy $ _run_closure2.doCall (_GrailsTest_groovy: 147) bei _GrailsTest_groovy $ _run_closure1_closure19.doCall (_GrailsTest_groovy : 113) bei _GrailsTest_groovy $ _run_closure1.doCall (_GrailsTest_groovy: 96) bei TestApp $ _run_closure1.doCall (TestApp.groovy: 66) bei gant.Gant $ _dispatch_closure4.doCall (Gant.gr oovy: 324) bei gant.Gant $ _dispatch_closure6.doCall (Gant.groovy: 334) bei gant.Gant $ _dispatch_closure6.doCall (Gant.groovy) bei gant.Gant.withBuildListeners (Gant.groovy: 344) bei gant.Gant.this $ 2 $ mitBuildListeners (Gant.groovy) um gant.Gant $ this $ 2 $ withBuildListeners.callCurrent (Unbekannte Quelle) um gant.Gant.dispatch (Gant.groovy: 334) um gant.Gant.this $ 2 $ Versand (Gant.Groovy) um gant.Gant.invokeMethod (Gant.Groovy) um gant.Gant.processTargets (Gant.groovy: 495) um gant.Gant.processTargets (Gant.groovy: 480) verursacht durch : java.lang.InstantiationException

Ich verstehe nicht. Ich habe eine Instanz der Klasse erstellt und sie der Methode mockForConstraintsTests übergeben. Was mache ich falsch?

Antwort

2

Dieser ist tatsächlich ein Problem mit der Art und Weise, dass die mockForConstraintsTests Sachen in Grails eher als ein Problem arbeiten mit dieser Art von Mock im Allgemeinen in groovy verwenden.

Diese Art von Schein ist nur nicht kompatibel mit den Mocks, die von den MockForConstraintsTests erstellt werden. Wenn Sie diese Bibliothek benutzen wollen, hat John Recht damit, einfach nur einen konkreten Impl der Klasse zu erstellen und weiterzugeben.

Ich bin eigentlich kein großer Fan der Constraint-Spott-Sache, die in den letzten Versionen von Grails ist, da es nicht "echt" ist und so viel von dem verspotteten Zeug ist anders als der tatsächliche Code, der wann ausgeführt wird Verbindung zu einer echten Datenbank.Ich bevorzuge es, Integrationstests zu verwenden, um diese Art von Constraint zu testen.

Wenn Sie Ihren gleichen Testklasse in den Integrationstests setzen und entfernen die mockForConstraintsTests aufrufen, wird Ihr Code funktioniert:

package toplevel.domain 

import grails.test.* 

class PartyTests extends GrailsUnitTestCase { 
    Party party 
    protected void setUp() { 
     super.setUp() 
     party = [:] as Party 
    } 

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

    void testNullRolesIsValid() { 
     party.roles = null 
     assertTrue "The roles should be nullable", party.validate() 
    } 
} 

Ergebnisse:

Running 1 integration test... 
Running test PartyTests...PASSED 
Tests Completed in 226ms ... 
------------------------------------------------------- 
Tests passed: 1 
Tests failed: 0 
------------------------------------------------------- 
3

Sie müssen eine konkrete Party-Klasse bereitstellen, der Test versucht eine Instanz der Party-Klasse zu erstellen und kann nicht, da es abstrakt ist. Ich habe Ihren Test unten überarbeitet und die Orte kommentiert, an denen ich Änderungen vorgenommen habe.

package toplevel.domain 

import grails.test.* 
import toplevel.domain.* 

// Create a stub implementation class 
class PartyImpl extends Party { } 

class PartyTests extends GrailsUnitTestCase { 
    Party party 
    protected void setUp() { 
     super.setUp() 
     //party = [:] as Party 
     // Create an instance of the stub'd class 
     party = new PartyImpl() 
     //mockForConstraintsTests(Party, [party]) 
     // Need to pass in the concrete class as first arg 
     mockForConstraintsTests(PartyImpl, [party]) 
    } 

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

    void testNullRolesIsValid() { 
     party.roles = null 
     assertTrue "The roles should be nullable", party.validate() 
    } 
}