Как изменить метакласс класса для каждого теста
Я использую ExpandoMetaClass, чтобы сервис всегда возвращал успех в интеграционном тесте, но мне бы хотелось иметь один тест, который на самом деле не проходит.
Пример использования ExpandoMetaClass:
static {
ExpandoMetaClass someService = new ExpandoMetaClass(Object, false)
someService.accessAnotherSystem = { return 'success' }
someService.initialize()
SomeService.metaClass = someService
}
Примечание: в настоящее время служба не определена для контроллера, но так как это пружинный компонент, ссылающийся на класс с именем SomeService
лайк someService.accessAnotherSystem()
работает просто отлично т.е. нету def someService
в контроллере.
Поэтому я не могу сделать controller.someService.metaClass.accessAnotherSystem = { return 'failure'}
из интеграционного теста.
Также обратите внимание: это интеграционный тест для веб-потока.
Можно ли сбросить метакласс для одного теста или в каком-то другом тесте то, что я хочу?
1 ответ
Приведенное ниже работает нормально, если тест выполняется сам по себе, однако ExpandoMetaClass переопределяется, если перед ним запускается другой тест, использующий SomeService. Я открою еще один вопрос для этой проблемы.
static {
ExpandoMetaClass someService = new ExpandoMetaClass(Object, false)
someService.invokeMethod = { String name, args ->
def result = 'success'
if(name.equals('accessAnotherSystem')
{
StackTraceUtils.sanitize(new Throwable()).stackTrace.each
{
if(it.methodName.equals('method_I_Want_failure')
{
result = 'exception'
}
}
return result
}
def validMethod = SomeService.metaClass.getMetaMethod(name, args)
if (validMethod != null)
{
validMethod.invoke(delegate, args)
}
else
{
SomeService.metaClass.invokeMissingMethod(delegate, name, args)
}
}
someService.initialize()
SomeService.metaClass = someService
}