2015-09-03 193 views
4

嘲笑springSecurityService我單元測試在內部創建一個用戶實例一個Grails控制器的方法。用戶域類使用了Spring安全插件的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() 
} 
} 
+0

用戶如何域可以訪問springSecurityService? – Yaro

回答

0

您可以使用此代碼在User編碼密碼:

def beforeInsert() { 
    encodePassword() 
} 

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

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

springSecurityService爲null,encodePassword不叫和NPE不提高

嘲笑服務
+0

如果你改變你的用戶類代碼,銘記,這是改變類的行爲,而不是metaClassing SpringSecurityService用於測試的持續時間,由Emmanuel如下所述。 – railsdog

+0

測試是如此奇妙的工具,允許檢查您的代碼功能和設計/實現失敗。也許你只需要檢查你的代碼而不是強制測試。 –

3

的一種方式是使用Groovy的MetaClass

import grails.test.mixin.Mock 
import grails.plugin.springsecurity.SpringSecurityService 

... 
@Mock(SpringSecurityService) 
class MemberControllerSpec extends Specification { 

    def setupSpec() { 
     SpringSecurityService.metaClass.encodePassword = { password -> password } 
    } 

    def cleanupSpec() { 
     SpringSecurityService.metaClass = null 
    } 
.... 

在此示例中,撥打SpringSecurityService.encodePassword()的電話將以純文本格式返回密碼。

使用嘲笑的一種方法進行了討論here

+0

這種方法對我不起作用。我的規格測試控制器而不是用戶類。在現場後面,控制器方法創建一個用戶實例。並且該用戶實例沒有注入安全服務(因爲它是一個單元測試) – saw303