在 Grails 中模拟私有方法

Mock private method in Grails

我是 grails 的新手,在集成方面遇到困难 testing.I 有一项服务 class 从私有方法内部调用外部服务。有没有办法模拟这个私有方法,这样我就可以避免调用外部服务进行集成测试?请指导我。

示例代码如下:

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

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 调用,而是实际进行原始 rest 调用并从数据库中获取值。我做错了什么吗?

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

如果你想在进行电汇之前进行模拟,你应该使用 RestTemplate 的模拟实例来完成(这意味着你必须让它是可注入的——无论如何这是一个好主意,因为它是一个外部依赖)。但是 spring 提供了一个更好的解决方案: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