1

In unit test cases of controllers i'm only able to inject the services that are used in the corresponding controller.But if say one service in controller injects another service then my test cases gets failed i.e. can not invoke service method on null object.

@TestFor(MyController)
@Mock(MyService)
class MyControllerSpec extends Specification {
    void "test something"(){
        when:
            controller.method1();
        then:
            //something
    }

}

class MyController(){
    MyService myService

    void method1(){
        myService.serviceMethod()       
    }   
}

class MyService(){
    AnotherService anotherService
    void serviceMethod(){
        anotherService.anotherServiceMethod()
    }
}

class AnotherService(){
    void anotherServiceMethod(){
    \\something
    }
}

in this case, I'm getting can not invoke "anotherServiceMethod" on null object. is there any way to test this type of controller? and is it a good approach to inject a service in another service?

4

1 回答 1

9

将服务注入另一个服务是一种很好的方法,这没有错。

为了使这个测试有效,有几种方法。

推荐 - 单元测试应该只测试单个类的行为,如果你需要测试完整的功能,集成/功能规范会更好。在这种情况下,您执行控制器的方法,但所有其他被调用的类都是您预测返回什么值的模拟。然后为 MyService 和 AnotherService 创建单独的测试。在这种情况下,您的测试可能如下所示:

@TestFor(MyController)
class MyControllerSpec extends Specification {
    void "test something"(){
        given:
            MyService myService = Mock()
            controller.myService = myService
        when:
            controller.method1();
        then:
            1 * myService.serviceMethod() >> someResult
            //something
    }
}

此测试确保调用 serviceMethod() 并强制它返回您对该规范的期望。如果在其他情况下(抛出异常,如果/否则你想确保 serviceMethod() 没有被调用,你可以使用0 * myService.serviceMethod()

不推荐:如果您坚持在本规范中调用服务方法,您可以创建模拟AnotherService并将其设置在控制器中可用的服务上。就像是:

AnotherService anotherService = Mock()
controller.myService.anotherService = anotherService
...
then:
1 * anotherService.callAnotherMethod()

也许也可以使用@Mock([MyService, AnotherService]),但我没有测试它。我们使用集成测试来测试集成 - 一切都为您注入,您可以在普通类上工作。

于 2016-03-04T18:19:03.447 回答