在服务测试中第二次使用GrailsApplication Mock失败

时间:2011-06-16 04:49:37

标签: unit-testing grails groovy mocking

我正在对Grails服务进行单元测试,并使用Mocks来模拟调用 GrailsApplication类。我有一个成功的测试但是当我尝试时 后续测试他们失败了。我使用需求来模拟isDomainClass 方法。我试过从测试中复制并粘贴代码 成功的测试方法失败但第二次相同的代码 运行失败,说不再需要调用isDomainClass。我 怀疑方法之间有些漏洞,但我看不出它在哪里。

我已经尝试过的事情:

  • 从命令行运行测试(我在SpringSource Tool Suite版本2.7.0.201105292341-M2下运行测试。)
  • 将失败的测试移动到另一个测试类(首先运行的测试成功)
  • 将demand子句中的数字范围更改为1..5(第二次测试仍然失败)

以下是我的测试用例的相关部分:

package simulation

import grails.test.*
import org.joda.time.*
import org.codehaus.groovy.grails.commons.GrailsApplication

class ObjectSerializationServiceTests extends GrailsUnitTestCase {

       def objectSerializationService

   protected void setUp() {
       super.setUp()
               objectSerializationService = new ObjectSerializationService()
   }

   protected void tearDown() {
       super.tearDown()
               objectSerializationService = null
   }

       void testDomainObjectSerialization() {
               def otherControl = mockFor(GrailsApplication)
               otherControl.demand.isDomainClass(1..1) {true}
               otherControl.demand.getDomainClass(1..1) {className ->
                       assert className == "simulation.TestDomainClass"
                       TestDomainClass.class
               }
               objectSerializationService.grailsApplication = otherControl.createMock()

               def now = new DateTime()
               def testObject = new TestDomainClass([id:57, someOtherData:"Some Other
Data", theTime:now])
               def testInstances = [testObject]
               mockDomain(TestDomainClass, testInstances)

               def serialized = objectSerializationService.serializeObject(testObject)
               def deserialized =
objectSerializationService.deserializeObject(serialized)

               assert deserialized == testObject
               assert serialized.objectType == SerializedObject.ObjectType.DOMAIN

               otherControl.verify()
       }

   void testSerializableSerialization() {
               def otherControl = mockFor(GrailsApplication)
               otherControl.demand.isDomainClass(1..1) {true}
               otherControl.demand.getDomainClass(1..1) {className ->
                       assert className == "simulation.TestDomainClass"
                       TestDomainClass.class
               }
               objectSerializationService.grailsApplication = otherControl.createMock()

               def now = new DateTime()
               def testObject = new TestDomainClass([id:57, someOtherData:"Some Other
Data", theTime:now])
               def testInstances = [testObject]
               mockDomain(TestDomainClass, testInstances)

               def serialized = objectSerializationService.serializeObject(testObject)
               def deserialized =
objectSerializationService.deserializeObject(serialized)

               assert deserialized == testObject
               assert serialized.objectType == SerializedObject.ObjectType.DOMAIN

               otherControl.verify()
   }

}

输出:

Testcase: testDomainObjectSerialization took 0.943 sec
Testcase: testSerializableSerialization took 0.072 sec
       FAILED
junit.framework.AssertionFailedError: No more calls to 'isDomainClass'
expected at this point. End of demands.
       at grails.test.MockClosureProxy.doBeforeCall(MockClosureProxy.java:66)
       at grails.test.AbstractClosureProxy.call(AbstractClosureProxy.java:74)
       at
simulation.ObjectSerializationService.serializeObject(ObjectSerializationService.groovy:20)
       at simulation.ObjectSerializationService$serializeObject.call(Unknown
Source)
       at
simulation.ObjectSerializationServiceTests.testSerializableSerialization(ObjectSerializationServiceTests.groovy:68)

1 个答案:

答案 0 :(得分:1)

我在多个测试用例中尝试在jms Message接口上使用mockFor时遇到了类似的错误。

我通过创建一个从需要模拟的界面扩展的自定义界面来解决这个问题。您可以使用自定义界面来创建模拟。

e.g。

private interface GrailsApplicationTest1 extends GrailsApplication(){}
testOne(){
    def control = mockFor(GrailsApplicationTest1)
    //...rest of code
}

private interface GrailsApplicationTest2 extends GrailsApplication(){}
testTwo(){
    def control = mockFor(GrailsApplicationTest2)
    //...rest of code
}
//add more private interfaces for additional test cases..

我不确定为什么,但我认为mockFor在接口和非接口之间的行为不同。但这只是一个疯狂的猜测。