我如何测试注入到 Grails 中其他服务的服务?

How can I test a service injected to other service in Grails?

我在从其他服务调用服务时出错。

| Running 13 unit tests... 1 of 13
| Failure:  test myAction(MyServiceSpec)
2015.05.27/02:17:09  ERROR StackTrace -- Full Stack Trace:
java.lang.NullPointerException: Cannot invoke method saveUserRole() on null object

我做了如下两个服务。

class MyService {
    def userRoleService
    def myAction(){
        def userQuery = User.where{username == "test1"}.get()
        def roleQuery = Role.where{authority == "ROLE_ADMIN"}.get()
        if (userQuery && roleQuery){
            userRoleService.saveUserRole(userQuery, roleQuery)
        }
    }
}

class UserRoleService{
    def saveUserRole(user, role){
        new UserRole(role: role, user:user).save(flush: true)
    }
}

我想测试 MyServicemyAction(),所以我做了 MyServiceSpec 如下。

@TestFor(DatabaseService)
@TestMixin(DomainClassUnitTestMixin)
class MyServiceSpec extends Specification {
    def userRoleService 
    def setup() { }
    def cleanup() { }
    void "test myAction"(){
        setup:
        mockDomain( Role,[ [authority:"ROLE_ADMIN"], [authority:"ROLE_USER"] ] )
        mockDomain( User,[ [username:"test1",password:"1234"] ] )
        mockDomain( UserRole )

        when: "call the action"
        service.myAction()

        then:
        UserRole.count() == 1
    }   
}

调用userRoleService.saveUserRole(userQuery, roleQuery)时出现此错误。

如何测试 MyServicemyAction() 而没有错误?

----

更新

我更改了规格 Class 如下。

@TestFor(DatabaseService)
@TestMixin(DomainClassUnitTestMixin)
class MyServiceSpec extends Specification {
    def setup() { }
    def cleanup() { }
    void "test myAction"(){
        setup:
        mockDomain( Role,[ [authority:"ROLE_ADMIN"], [authority:"ROLE_USER"] ] )
        mockDomain( User,[ [username:"test1",password:"1234"] ] )
        mockDomain( UserRole )
        def userQuery = User.where{username == "test1"}.get()
        def roleQuery = Role.where{authority == "ROLE_ADMIN"}.get()
        def mockUserRoleService = Mock(UserRoleService){
            1 * saveUserRole(userQuery, roleQuery) >> new UserRole(role: roleQuery, user:userQuery).save(flush: true)
        }
        service.userRoleService = mockUserRoleService

        when: "call the action"
        service.myAction()

        then:
        UserRole.count() == 1
    }   
}

测试识别服务class,谢谢。

但是好像这个测试用例不好或者这个程序设计的不好。

你对引用这段代码有什么建议吗?

根据评论,我更改了规格 Class 如下。

@TestFor(DatabaseService)
@TestMixin(DomainClassUnitTestMixin)
class MyServiceSpec extends Specification {
    def setup() { }
    def cleanup() { }
    void "test myAction"(){
        setup:
        mockDomain( Role,[ [authority:"ROLE_ADMIN"], [authority:"ROLE_USER"] ] )
        mockDomain( User,[ [username:"test1",password:"1234"] ] )
        mockDomain( UserRole )
        def userQuery = User.where{username == "test1"}.get()
        def roleQuery = Role.where{authority == "ROLE_ADMIN"}.get()
        def mockUserRoleService = Mock(UserRoleService){
            1 * saveUserRole(userQuery, roleQuery) >> new UserRole(role: roleQuery, user:userQuery).save(flush: true)
        }
        service.userRoleService = mockUserRoleService

        when: "call the action"
        service.myAction()

        then:
        UserRole.count() == 1
    }   
}

测试识别服务class,谢谢。

但是好像这个测试用例不好或者这个程序设计的不好

您对引用此代码有什么建议吗?