Unit testing Abstract classes in 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) at grails.test.MockUtils $ prepareForConstraintsTests.call(未知 来源)at grails.test.GrailsUnitTestCase.mockForConstraintsTests(GrailsUnitTestCase.groovy:111) 在PartyTests.setUp(PartyTests.groovy:9)at _GrailsTest_groovy $ _run_closure4.doCall(_GrailsTest_groovy:203)_GrailsTest_groovy $ _run_closure4.call(_GrailsTest_groovy)_GrailsTest_groovy $ _run_closure2.doCall(_GrailsTest_groovy:147)at _GrailsTest_groovy $ _run_closure1_closure19.doCall(_GrailsTest_groovy:113) 在_GrailsTest_groovy $ _run_closure1.doCall(_GrailsTest_groovy:96)at at TestApp $ _run_closure1.doCall(TestApp.groovy:66)at gant.Gant $ _dispatch_closure4.doCall(Gant.groovy:324)at gant.Gant $ _dispatch_closure6.doCall(Gant.groovy:334)at gant.Gant $ _dispatch_closure6.doCall(Gant.groovy)at gant.Gant.withBuildListeners(Gant.groovy:344)at gant.Gant.this $ 2 $ withBuildListeners(Gant.groovy)at gant.Gant $ this $ 2 $ withBuildListeners.callCurrent(Unknown Source)at gant.Gant.dispatch(Gant.groovy:334)at 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方法。我做错了什么?
答案 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()
}
}
答案 1 :(得分:2)
这实际上是一个问题,mockForConstraintsTests的东西在grails中工作,而不是在groovy中使用这种类型的mock的问题。
这种类型的mock与mockForConstraintsTests创建的模拟不兼容。如果你想使用这个库,John对于创建和传递一个简单的类的具体impl是正确的。
我实际上并不是最近版本的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
-------------------------------------------------------