0

Мое приложение имеет набор подклассов, которые расширяют определенный базовый класс.Единичный тестовый абстрактный класс с введенной услугой

BaseClass.groovy

abstract class Base { 

    def beforeInsert() { 
     userCreated = springSecurityService.currentUser 
    } 

    /* other stuff */ 

} 

ConcreteClass.groovy

class Concrete extends Base { 

    /* stuff, doesn't matter */ 

} 

И я пишу тест, который должен показать несколько Бетоны:

RelatedServiceSpec.groovy

def "under x circumstances, check for all instances that meet y criteria"() { 

    setup: "create 3 concrete classes" 
    (1..3).each { new Concrete(a: 'yes').save(validate: false) } 

    /* and then the actual test ... */ 

} 

Проблема возникает, когда я сохраняю экземпляров, из-за этого springSecurityService в BaseClass. Я не могу найти способ заглушить его для модульного теста!

  • Я не могу @Mock абстрактного класса, который необходим для использования defineBeans.
  • Base.springSecurityService повышает NPE.
  • Base.metaClass.springSecurityService и Base.metaClass.static.springSecurityService скомпилировано, но не работает.
  • И, видимо, вы не можете переопределять события в Grails, поэтому я не могу просто обойти beforeInsert, и все будет хорошо.

Кто-нибудь знает, как выполнить тестирование абстрактного класса с помощью введенной услуги?

EDIT

Это не произошло со мной, чтобы ввести услугу в класс реализации! Я попробую!

+0

Как вы относитесь к пользователю Создано, если нет сеанса/springSecurity вообще? например пакетное задание, создающее эти объекты или в бутстрапе? – cfrick

+0

Эта проблема не возникла. Они в настоящее время создаются непосредственно пользователем или являются побочным эффектом другого действия пользователя. Как его следует обрабатывать, и это ключ к пониманию того, как справиться с этой ситуацией? –

+0

Я просто хотел узнать или поднять вопрос. если они могут быть нулевыми, просто используйте SpringSecurityService? .currentUser или если пользователь по умолчанию (система, admin, ...) просто назначает его там. исходный вопрос остается действительным независимо. – cfrick

ответ

0

Что произойдет, если вы создадите реализацию beforeInsert(), которая вызывает вызовы beforeInsert(), и затем вы переопределяете производные классы для своих тестов? Я не пробовал это, поэтому не знаю, будет ли это работать, но это может стоить того, чтобы сделать бетон Base.

abstract class Base { 

    def beforeInsert() { 
     beforeInsertImpl() 
    } 

    def beforeInsertImpl() { 
     userCreated = springSecurityService.currentUser 
    } 

    /* other stuff */ 
} 

В тестах:

setup: "create 3 concrete classes" 
    (1..3).each { 
     def concrete = new Concrete(a: 'yes') 
     concrete.metaClass.beforeInsertImpl { /* do something with userCreated here */} 
     concrete.save(validate: false) 
    } 
+0

Неплохая идея, возможно, придется попробовать, если инъекция службы в производный класс не работает. –

0
Concrete.metaClass.getSpringSecurityService = { 
    return [ 
     getCurrentUser: { 
      return new User() 
     } 
    ] as SpringSecurityService 
} 

вы можете попробовать это? , конечно, это должно идти до вызова нового Concrete()

+0

Мне не пришло в голову внедрить службу в класс внедрения! Я попробую! –

Смежные вопросы