在Grails中模拟私有方法

时间:2015-04-08 04:02:46

标签: grails integration-testing spock

我是grails的新手并且在集成测试方面遇到了困难。我有一个服务类,它在内部通过私有方法调用外部服务。有没有办法模拟这个私有方法,以便我可以避免外部服务调用集成测试?请指导我。

以下示例代码:

import org.springframework.web.client.RestTemplate;

public class Service {
   final static RestTemplate REST = new RestTemplate()

   def get() {      
    def list = REST.getForObject(url, clazzObject, map) 
    list
}
}

集成测试类

class RackServiceIntegrationSpec extends IntegrationSpec {
     def service = new Service()

     void testApp(){
        setup:
        def testValues = ["name1", "name2"]
        service.metaClass.get = {String url, Class clazz, Map map -> testValues}

        when:
        def val = service.get()

        then:
        val.get(0) == 'name1'

    }
}

它不是模拟其余的调用,而是实际进行原始的rest调用并从数据库中获取值。我在这里做错了吗?

1 个答案:

答案 0 :(得分:0)

正如@Opal已经评论过 - 你应该切断外部依赖关系,而不是模拟服务的内部细节(比如私有方法)。但这当然只适用于单元测试类型的测试。根据您的测试目标,您可以切断外部内容或进行实际调用,并在另一侧使用模拟(两者都是不同级别的两个有效测试)。

如果你想在进行电汇之前进行模拟,你应该使用RestTemplate的模拟实例(这意味着你必须让它可以注入 - 这无论如何都是一个好主意,因为它是一个外部依赖)。但是春天提供了更好的解决方案:MockRestServiceServer

class RackServiceIntegrationSpec extends IntegrationSpec {
 def service = new Service()
   def 'service calls the external http resource correct and returns the value'() {
    setup: 'create expectations on the http interactions'
    MockRestServiceServer mockServer  = MockRestServiceServer.createServer(service.REST)
    mockServer.expect(requestTo("/customers/123")).andRespond(withSuccess("Hello world", MediaType.TEXT_PLAIN));

    when: 'service gets called'
    def val = service.get()

    then: 'http interactions were successful given the assertions above'
    mockServer.verify();

    and: 'your other assertions'
    val.get(0) == 'name1'

  }
}

有关详细信息,请参阅spring testing documentation