2009-07-11 56 views
1

Unit testing Abstract classes in GroovymockForConstraintsTests抽象Groovy類

我問以前的單元測試和嘲弄域類的問題,但我不認爲我是不夠具體。我有一個域類:

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 
} 

這裏是我的單元測試:

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() 
    } 
} 

以下是測試結果: 無法創建類[toplevel.domain.Party]的新實例!

org.codehaus.groovy.grails.exceptions.NewInstanceCreationException: 無法創建類[toplevel.domain.Party]的新實例!在 grails.test.MockUtils.prepareForConstraintsTests(MockUtils.groovy:540) 在grails.test.MockUtils $ prepareForConstraintsTests.call(未知 來源)在 grails.test.GrailsUnitTestCase.mockForConstraintsTests(GrailsUnitTestCase.groovy:111) 在PartyTests.setUp(PartyTests.groovy:9)在 _GrailsTest_groovy $ _run_closure4.doCall(_GrailsTest_groovy:203)在_GrailsTest_groovy $ _run_closure4.call(_GrailsTest_groovy)在_GrailsTest_groovy $ _run_closure2.doCall(_GrailsTest_groovy:147)在_GrailsTest_groovy $ _run_closure1_closure19.doCall(_GrailsTest_groovy :113) at _GrailsTest_groovy $ _run_closure1.doCall(_GrailsTest_groovy:96)at TestApp $ _run_closure1.doCall(TestApp.groovy:66)at gant.Gant $ _dispatch_closure4.doCall(Gant.gr oovy:324)在 gant.Gant $ _dispatch_closure6.doCall(Gant.groovy:334)在 gant.Gant $ _dispatch_closure6.doCall(Gant.groovy)在 gant.Gant.withBuildListeners(Gant.groovy:在 344) gant.Gant.this $ 2 $ withBuildListeners(Gant.groovy)在 gant.Gant $這個$ 2 $ withBuildListeners.callCurrent(來源不明)在 gant.Gant.dispatch(Gant.groovy:334)在 gant.Gant.this $ 2 $ dispatch(Gant.groovy)at gant.Gant.invokeMethod(Gant.groovy)at gant.Gant.processTargets(Gant.groovy:495)at gant.Gant.processTargets(Gant.groovy:480) : java.lang.InstantiationException

我不明白。我創建了該類的一個實例,並將其提供給mockForConstraintsTests方法。我究竟做錯了什麼?

回答

2

這實際上是與該mockForConstraintsTests東西的作品Grails中,而不是使用這種類型的模擬的一般常規問題的方式的問題。

這種類型的模擬與mockForConstraintsTests正在創建的模擬不兼容。如果你想使用這個庫,約翰是正確的,只是創建和傳遞一個簡單的具體實例。

我實際上並不是約束嘲笑最近版本的grails中的東西的大粉絲,因爲它不是「真實」的,而且這些嘲諷的東西與實際運行的代碼相比是不同的連接到一個真實的數據庫。我更喜歡使用集成測試來測試這種約束。

如果你把你的相同測試類的集成測試和刪除mockForConstraintsTests通話時,您的代碼將工作:

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() 
    } 
} 

結果:

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

你需要提供一個具體的Party類,測試試圖創建一個Party類的實例,因爲它是抽象的,所以不能。我已經在下面重新進行了測試,並評論了我所做的更改。

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() 
    } 
}