Unit testing Grails:在单元测试期间从服务中的Datamodel对象获取IndexOutOfBoundsException

Unit testing Grails:在单元测试期间从服务中的Datamodel对象获取IndexOutOfBoundsException,unit-testing,grails,gorm,grails-2.0,Unit Testing,Grails,Gorm,Grails 2.0,我有一个简单的Customer+PaswordReset数据模型 在我的PasswordService中,我调用PasswordReset.findByUsername()和save(),它工作正常 然后我做了PasswordServiceTests,它有@Mock([Customer,PasswordReset]) 在该测试中,我创建了一个新的Customer对象,并使用Customer.save和PasswordReset.findByUsername()。两者都很好 测试调用service

我有一个简单的Customer+PaswordReset数据模型

在我的PasswordService中,我调用PasswordReset.findByUsername()和save(),它工作正常

然后我做了PasswordServiceTests,它有@Mock([Customer,PasswordReset]) 在该测试中,我创建了一个新的Customer对象,并使用Customer.save和PasswordReset.findByUsername()。两者都很好

测试调用service.initatePasswordReset()(PasswordService),它成功地使用了Customer.findByUsername()和PasswordReset.save()

在测试中,我然后调用PasswordReset.findByUsername(…),并找到服务.initiateReset()生成的对象

但是,当我调用另一个方法:service.performReset()时,它通过使用customer.findByUsername(..)成功加载customer对象,修改customer密码字段并尝试执行customer.save()

以下错误是由PasswordService中的customer.save()引起的。谁能告诉我怎么了

java.lang.IndexOutOfBoundsException:索引:1,大小:1 位于java.util.ArrayList.rangeCheck(ArrayList.java:604) 在java.util.ArrayList.remove处(ArrayList.java:445) 位于org.grails.datastore.mapping.simple.engine.SimplePentitypersister$1.deindex(SimplePentitypersister.groovy:101) 位于org.grails.datastore.mapping.engine.NativeEntryEntityPerister.UpdatePropertyIndexes(nativeEntryEntityPerister.java:1200) 位于org.grails.datastore.mapping.engine.nativeEntryEntityTyperSister.access$100(nativeEntryEntityTyperSister.java:55) 位于org.grails.datastore.mapping.engine.nativeEntryEntityTyperSister$4.run(nativeEntryEntityTyperSister.java:958) 位于org.grails.datastore.mapping.core.impl.PendingOperationExecution.executePendingOperation(PendingOperationExecution.java:36) 位于org.grails.datastore.mapping.core.AbstractSession.flushPendingOperations(AbstractSession.java:323) 位于org.grails.datastore.mapping.core.AbstractSession.FlushPendingUpdate(AbstractSession.java:302) 位于org.grails.datastore.mapping.core.AbstractSession.flush(AbstractSession.java:240) 位于org.grails.datastore.gorm.GormInstanceApi.doSave(GormInstanceApi.groovy:168) 位于org.grails.datastore.gorm.GormInstanceApi$\u save\u closure4.doCall(GormInstanceApi.groovy:143) 位于org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:301) 位于org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:34) 位于org.grails.datastore.gorm.GormInstanceApi.save(GormInstanceApi.groovy:142) 在com.foo.services.PasswordService.performPasswordReset(PasswordService.groovy:33)上 在com.foo.services.PasswordServiceTests.testResetPassword(PasswordServiceTests.groovy:47)

passwordservicestest.groovy

@TestFor(PasswordService)
@Mock([Customer, PasswordReset])
class PasswordServiceTests {

void setUp() {
    mockCodec(MD5Codec)
   // mockService(CustomerRegistrationService)
}

void testResetPassword() {
        Customer c = CustomerRegistrationServiceTests.makePrivateCustomer()
        c.sumUnpaidInvoices = 0
        c.sumOverdueInvoices = 0
        c.password = service.hashPassword(c)
        c.customerType = CustomerType.NormalCustomer.value

        c.save(flush: true);
        assertEquals("Mock DB does not contain 1 customer", 1, Customer.list().size())

        service.initiatePasswordReset(c.username)

        def pwReset = PasswordReset.findByUsername(c.username)
        println("psreset saved: " + pwReset.username + " / " + pwReset.code)
        assertEquals(c.username, pwReset.username)

        service.performPasswordReset(c.username, "test"); // CALLS METHOD BELOW
    }
}
PasswordService.groovy中的方法:

def performPasswordReset(String username, String newPassword) {
    Customer customer = Customer.findByUsername(username)
    if(customer != null) {
        customer.password = newPassword;
        customer.password = hashPassword(customer);

        customer.save(flush: true); // CAUSES THE ERROR
        ....
    }
}

看起来这个特定的错误与

customer.save(flush: true);

我想说hibernate还有一些东西需要持久化(以前的任何“非刷新保存”)但失败了。

我通过删除对服务中customer.save()的调用修复了这个问题,它不是必需的,甚至没有customer.save。当您更改密码(customer.password=“foo”)。

我刚刚遇到了这个问题,您的解决方案很有效……但我不明白为什么!至少我可以继续前进,但感觉我很快就会被咬。Grails Github问题中提到了这个错误: