mockForConstraintsTests抽象groovy类

时间:2009-07-11 05:55:43

标签: unit-testing grails groovy mocking

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方法。我做错了什么?

2 个答案:

答案 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
-------------------------------------------------------