代码之家  ›  专栏  ›  技术社区  ›  rooscous

Spock框架:间谍与使用实物或模拟的间谍相比的目的是什么?

  •  2
  • rooscous  · 技术社区  · 7 年前

    间谍总是基于真实的物体。因此,必须提供类类型而不是接口类型,以及该类型的任何构造函数参数。如果没有提供构造函数参数,则将使用默认构造函数类型。

    间谍的方法调用自动委托给真实对象。同样,从real objects方法返回的值通过spy传递回调用方。

    也:

    subscriber.receive(_) >> "ok"

    如果间谍只是真实对象和调用者之间的接口层,为什么不直接使用真实对象呢?使用间谍提供了什么,而使用真实对象或模拟对象却没有?

    3 回复  |  直到 4 年前
        1
  •  2
  •   Leonard Brünings    7 年前

    间谍可以在不同的场景中使用。然而,如果您可以在不借助间谍的情况下实现测试,这是很好的。

    (使用此功能前请三思。最好根据规范更改代码的设计。)

    1. 你可以删掉你不想发生的电话
    2. 您可以使用部分模拟来测试对象本身
    
        // this is now the object under specification, not a collaborator
        def persister = Spy(MessagePersister) {
          // stub a call on the same object
          isPersistable(_) >> true
        }
    
        when:
        persister.receive("msg")
    
        then:
        // demand a call on the same object
        1 * persister.persist("msg")
    
    

    示例和引用来自文档@ http://spockframework.org/spock/docs/1.1/all_in_one.html#Spies

        2
  •  1
  •   Dmytro Maslenko    7 年前

    MyDomainClass myRealObjectWithMockedMethod = new MyDomainClass() {
        @Override
        Object doSomething() {
            return "hard coded or mocked result";
        }
    }
    
    // test what you need
    myRealObjectWithMockedMethod.action();
    

    注意,这种方法只适用于被重写的方法不是final。否则Spy将帮助定义此方法的行为。

        3
  •  0
  •   mszalbach    7 年前

    间谍可以使用原始对象,但也可以模拟一种方法。例如,您有一个类,您想在其中测试 toString() 方法但这会调用一个长时间运行的方法,该方法需要一些外部访问,如数据库。在这种情况下,您使用间谍并让长时间运行的方法返回一些测试字符串,然后使用 toString

    或者像斯波克的例子一样 subscriber.receive 可能需要一个发送异步消息的服务器。为编写测试 subscriber 不依赖服务器或处理异步复杂性,您让间谍返回 ok 并且可以轻松测试依赖于服务器的方法 .