2009-07-11 71 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() 
    } 
}