我正在对内部创建用户实例的Grails Controller 方法进行单元测试。用户域类使用Spring Security插件的springSecurityService对密码进行编码,然后再将其插入数据库。

有没有一种方法可以从我的单元测试中模拟springSecurityService来消除该错误?

 Failure:  Create new individual member(MemberControllerSpec)
|  java.lang.NullPointerException: Cannot invoke method encodePassword() on null object

请在下面找到我的单元测试。
@TestMixin(HibernateTestMixin)
@TestFor(MemberController)
@Domain([User, IndividualPerson])
class MemberControllerSpec extends Specification {

void "Create new individual member"() {

    given:
    UserDetailsService userDetailsService = Mock(UserDetailsService)
    controller.userDetailsService = userDetailsService

    def command = new IndividualPersonCommand()
    command.username = '[email protected]'
    command.password = 'What ever'
    command.firstname = 'Scott'
    command.lastname = 'Tiger'
    command.dob = new Date()
    command.email = command.username
    command.phone = '89348'
    command.street = 'A Street'
    command.housenumber = '2'
    command.postcode = '8888'
    command.city = 'A City'

    when:
    request.method = 'POST'
    controller.updateIndividualInstance(command)

    then:
    view == 'createInstance'

    and:
    1 * userDetailsService.loadUserByUsername(command.username) >> null

    and:
    IndividualPerson.count() == 1

    and:
    User.count() == 1

    cleanup:
    IndividualPerson.findAll()*.delete()
    User.findAll()*.delete()
}
}

最佳答案

您可以使用此代码在User中编码密码:

def beforeInsert() {
    encodePassword()
}

def beforeUpdate() {
    if (isDirty('password')) {
        encodePassword()
    }
}

protected void encodePassword() {
    password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}

springSecurityService为null时,不调用encodePassword并且不引发NPE

09-04 10:29