【问题标题】:Mock object used insided the to be tested function using spock使用 spock 在要测试的函数内部使用的模拟对象
【发布时间】:2018-03-04 10:50:59
【问题描述】:

我可以通过多种方式模拟要测试的类的函数。但是如何模拟在要测试的方法中创建的对象? 我有这个要测试的课

 @Grab('org.codehaus.groovy.modules.http-builder:http-builder:0.7')
 import groovyx.net.http.HTTPBuilder
 class totest {
     def get() {
         def http = new HTTPBuilder('http://www.google.com')
         def html = http.get( path : '/search', query : [q:'Groovy'] )
         return html
     }   
 }     

如何模拟 http.get 以便测试 get 函数:

class TestTest extends Specification {
     def "dummy test"() {
         given:
             // mock httpbuilder.get to return "hello"
             def to_test = new totest()
         expect:                                                                                               
             to_test.get() == "hello"
     }   
 }

【问题讨论】:

    标签: unit-testing groovy mocking spock


    【解决方案1】:

    更好的方法是将 HTTPBuilder 传递给您的构造函数,然后测试代码可以通过测试模拟。

    但是,如果您想模拟代码内部的类构造,请在此处查看使用 GroovySpy 和 GroovyMock 模拟构造函数和类:http://spockframework.org/spock/docs/1.0/interaction_based_testing.html

    您需要执行以下代码:

    import spock.lang.Specification
    
    import groovyx.net.http.HTTPBuilder
    
    class totest {
        def get() {
            def http = new HTTPBuilder('http://www.google.com')
            def html = http.get( path : '/search', query : [q:'Groovy'] )
            return html
        }
    }
    
    class TestTest extends Specification{
    
        def "dummy test"() {
    
            given:'A mock for HTTP Builder'
            def mockHTTBuilder = Mock(HTTPBuilder)
    
            and:'Spy on the constructor and return the mock object every time'
            GroovySpy(HTTPBuilder, global: true)
            new HTTPBuilder(_) >> mockHTTBuilder
    
            and:'Create object under test'
            def to_test = new totest()
    
            when:'The object is used to get the HTTP result'
            def result = to_test.get()
    
            then:'The get method is called once on HTTP Builder'
            1 * mockHTTBuilder.get(_) >> { "hello"}
    
            then:'The object under test returns the expected value'
            result == 'hello'
        }
    }
    

    【讨论】:

    • 致 OP:是的,实际上,全局 Groovy 模拟是在这里工作的技术技巧,但是 (1) 它只适用于 Groovy 代码,而不适用于 Java,而且 - 最重要的是 - (2)每当您需要 Groovy 模拟,尤其是全局模拟,或用于静态方法等的 PowerMock 等工具时,所有警钟都应该响起。糟糕的应用程序设计是重构以实现更好的解耦(依赖注入而不是类自己创建依赖关系,隐藏在方法体中)和更好的可测试性的原因。这绝不是升级“测试库”以避免重构的理由。
    【解决方案2】:

    你在这里测试什么?你关心如何方法得到它的结果吗?你肯定更关心它得到正确的结果吗?在这种情况下,应该更改方法以便 URL 是可配置的,然后您可以建立一个返回已知字符串的服务器,并检查是否返回了字符串

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      • 1970-01-01
      相关资源
      最近更新 更多