2012-06-13 3 views
0

나는 간단한 Customer + PaswordReset 데이터 모델을 가지고 있습니다.Grails : 단위 테스트 동안 서비스의 Datamodel 객체에서 IndexOutOfBoundsException 가져 오기

내 PasswordService에서 PasswordReset.findByUsername() 및 save()를 호출하면 정상적으로 작동합니다.

그런 다음 @Mock ([Customer, PasswordReset])이있는 PasswordServiceTests를 작성했습니다. 이 테스트에서 새 Customer 객체를 만들고 Customer.save를 사용하고 PasswordReset.findByUsername()을 사용합니다. 둘 다 잘 작동합니다.

Customer.findByUsername() 및 PasswordReset.save()를 모두 사용하는 테스트 호출 service.initatePasswordReset() (PasswordService).

테스트에서 나는 PasswordReset.findByUsername (...)을 호출하고 service.initiateReset()에 의해 만들어진 객체를 찾는다. 나는 다른 방법을 호출 할 때

는 그러나 : service.performReset(), 성공적으로 Customer.findByUsername (..)를 사용하여 고객의 개체를로드, 고객 암호 필드를 수정하고 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.SimpleMapEntityPersister $ 1.deindex (SimpleMapEntityPersister.groovy에서 : 101) org.grails.datastore.mapping.engine.NativeEntryEntityPersister.updatePropertyIndices에서 (NativeEntryEntityPersister.java:1200) 에서 org.grails.datastore.mapping.engine.NativeEntryEntityPersister.access $ 100 (NativeEntryEntityPersister.java:55) at org.grails.datastore.mapping.engine.NativeEntryEntityPersister $ 4.run (NativeEntryEntityPersister.java:958))에 org.grails.datastore.mapping.core.AbstractSession.flushPendingOperations org.grails.datastore.mapping.core.impl.PendingOperationExecution.executePendingOperation (PendingOperationExecution.java:36) (AbstractSession.java:323) 에서 조직에서 (AbstractSession.java : 302) at org.grails.datastore.gorm.GormInstanceApi $ _save_closure4.doCall (GormInstanceApi.groovy 143)에서 : .GormInstanceApi.doSave (168 GormInstanceApi.groovy) org.grails.datastore.mapping.core.DatastoreUtils.execute에서 (DatastoreUtils .java : 301) at org.grails.datastore.gorm.AbstractDatastoreApi.execute (Abs (GormInstanceApi.groovy : 142) 에서 com.foo.services.PasswordService.performPasswordReset (PasswordService.groovy : 33) com.foo에서 services.PasswordServiceTests.testResetPassword (PasswordServiceTests.groovy 47)

PasswordServiceTest.groovy PasswordService에

@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 
    } 
} 

방법.그루비 :

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 
     .... 
    } 
} 

답변

2

서비스의 customer.save()에 대한 호출을 제거하여이 문제를 해결했지만 고객이 변경하지 않아도 customer.save를 사용하지 않아도 비밀번호가 자동으로 데이터베이스에 저장됩니다 (customer.password = " foo ").

+0

방금이 문제를 접했고 솔루션이 작동하지만 ... 이유를 이해할 수 없습니다! 적어도 나는 계속 전진 할 수는 있지만, 언젠가는 물기가 될 것 같은 느낌이 든다. 이 버그는 Grails Github 문제에서 언급됩니다 : https://github.com/grails/grails-core/issues/9139 – mrArias

0

그것은이 특정 오류가 정말

customer.save(flush: true); 

관련이없는 것처럼 내가 그 최대 절전 모드가 지속 될 필요가 뭔가 다른 (저장 이전 "비 플러시를 가지고 말할 것 같습니다 ") 그 실패합니다.