I use both Spring and Spock plugins in my current project. I wrote a bunch of test cases in Spock. All are passing without any error (All are GREEN!). But the same tests are failing if I try to test the app after some time. I don’t why this happens. This is the code (one of my failing test):
def 'list action: 1 user'() {
setup:
mockDomain(User,[userInstance])
expect:
controller.list() == [userInstanceList: [userInstance] , userInstanceTotal: 1]
params.max == 10
where:
userInstance = new User(username:"antoaravinth",password:"secrets")
}
I get a big error for this:
java.lang.NullPointerException: Cannot invoke method encodePassword() on null object
at mnm.schedule.User.encodePassword(User.groovy:34)
at mnm.schedule.User.beforeInsert(User.groovy:42)
at org.grails.datastore.gorm.events.DomainEventListener.invokeEvent(DomainEventListener.java:188)
at org.grails.datastore.gorm.events.DomainEventListener.beforeInsert(DomainEventListener.java:110)
at org.grails.datastore.gorm.events.DomainEventListener.onPersistenceEvent(DomainEventListener.java:73)
at org.grails.datastore.mapping.engine.event.AbstractPersistenceEventListener.onApplicationEvent(AbstractPersistenceEventListener.java:46)
at org.grails.datastore.mapping.engine.EntityPersister.cancelInsert(EntityPersister.java:227)
at org.grails.datastore.mapping.engine.NativeEntryEntityPersister.executeInsert(NativeEntryEntityPersister.java:1321)
at org.grails.datastore.mapping.engine.NativeEntryEntityPersister$1.run(NativeEntryEntityPersister.java:698)
at org.grails.datastore.mapping.core.impl.PendingOperationExecution.executePendingOperation(PendingOperationExecution.java:33)
at org.grails.datastore.mapping.core.AbstractSession.flushPendingOperations(AbstractSession.java:322)
at org.grails.datastore.mapping.core.AbstractSession.flushPendingInserts(AbstractSession.java:314)
at org.grails.datastore.mapping.core.AbstractSession.flush(AbstractSession.java:237)
at org.grails.datastore.mapping.query.Query.flushBeforeQuery(Query.java:596)
at org.grails.datastore.mapping.query.Query.list(Query.java:562)
at org.grails.datastore.mapping.query.Query.singleResult(Query.java:606)
at org.grails.datastore.gorm.GormStaticApi.count_closure11(GormStaticApi.groovy:311)
at org.grails.datastore.mapping.core.DatastoreUtils.execute(DatastoreUtils.java:301)
at org.grails.datastore.gorm.AbstractDatastoreApi.execute(AbstractDatastoreApi.groovy:34)
at org.grails.datastore.gorm.GormStaticApi.count(GormStaticApi.groovy:307)
at mnm.schedule.UserController.list(UserController.groovy:241)
at mnm.schedule.UserControllerSpec.list action: 1 user(UserControllerSpec.groovy:34)
The Domain class :
package mnm.schedule
import org.example.*;
class User extends SecUser {
Profile profile
String username
String password
static constraints = {
username(unique:true,size:3..15, blank:false)
password(blank:false)
String toString() {
this.username
}
static mapping = {
cache true
}
protected void encodePassword() {
password = springSecurityService.encodePassword(password)
}
Set<SecRole> getAuthorities() {
SecUserSecRole.findAllBySecUser(this).collect { it.secRole } as Set
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
}
The same test is passing at times and at time throwing this error. Whats wrong here? How can it pass at times and fail at times?
Thanks in advance.
Check this blog as an example of mocking springSecurityService in domain objects
http://www.block-consult.com/blog/2011/08/17/inject-spring-security-service-into-domain-class-for-controller-unit-testing/ or check https://stackoverflow.com/a/9789619/206351