Издеваться над синглтоном в Groovy - PullRequest
0 голосов
/ 02 июля 2018

В Groovy / Spock я могу издеваться над классом, выполнив:

def theClass = Mock(TheClass.class)

, а затем подключите этот экземпляр к тестируемому классу. А что если я захочу смоделировать класс, аннотированный как @ Singleon

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Вот небольшой класс инструментов, который вы можете использовать:

package de.scrum_master.stackoverflow

import java.lang.reflect.Field
import java.lang.reflect.Modifier

class GroovySingletonTool<T> {
  private Class<T> clazz

  GroovySingletonTool(Class<T> clazz) {
    this.clazz = clazz
  }

  void setSingleton(T instance) {
    // Make 'instance' field non-final
    Field field = clazz.getDeclaredField("instance")
    field.modifiers &= ~Modifier.FINAL
    // Only works if singleton instance was unset before
    field.set(clazz.instance, instance)
  }

  void unsetSingleton() {
    setSingleton(null)
  }

  void reinitialiseSingleton() {
    // Unset singleton instance, otherwise subsequent constructor call will fail
    unsetSingleton()
    setSingleton(clazz.newInstance())
  }
}

Просто позвоните setSingleton(Mock(TheClass)). Для получения дополнительной информации см. этот ответ , я не хочу повторять здесь весь пример кода.

Не стесняйтесь задавать дополнительные вопросы, если есть что-то, чего вы не понимаете.

0 голосов
/ 02 июля 2018

Вы можете использовать глобальные макеты

def publisher = new Publisher()
publisher << new RealSubscriber() << new RealSubscriber()

def anySubscriber = GroovyMock(RealSubscriber, global: true)

when:
publisher.publish("message")

then:
2 * anySubscriber.receive("message")
...