При использовании Grails с иерархией классов домена, подобной следующем:Grails: имитировать спящий режим прокси-сервер для тестирования
abstract class Vehicle { ... }
class Car extends Vehicle { ... }
class Motorcycle extends Vehicle { ... }
и сервис как следующее:
class VehicleService {
def startRepairing(Car car) { ... }
def startRepairing(Motorcycle motorcycle) { ... }
}
Мы очень часто мы сталкиваемся ошибки в тексте:
Нет подписи метода: VehicleService.startRepairing() применимо для типы аргументов: (Car _ $$ _ javassist_156) значения: [Id: 42343, класс: Car]. Возможные решения: startRepairing (Car)
Мы считаем, что это происходит потому, что мы получаем экземпляр Vehicle
из коллекции, такие как static hasMany = [vehicles: Vehicle]
, что приводит к прокси для реализации абстрактного класса Vehicle
, но не конкретного класса (Car
, Motorcycle
, и т.д).
Мы использовали, чтобы удалить тип аргумента из метода в качестве решения, но мы предпочли бы иметь его - код чист, перегрузка метода возможна, более IDE дружеская ...
Одно решения, мы думали о том, использовать пресловутый GrailsHibernateUtil.unwrapIfProxy, когда тип не соответствует какому-либо другому методу:
class VehicleService {
def startRepairing(Vehicle vehicle) {
startRepairing(GrailsHibernateUtil.unwrapIfProxy(vehicle))
}
def startRepairing(Car car) {
/* actual business logic here */
}
def startRepairing(Motorcycle motorcycle) {
/* actual business logic here */
}
}
Но тогда возникает вопрос, как мы можем проверить это? При запуске кода в разработке мы очень редко находим проблему javassist, и даже в производстве это происходит «случайно» (или, точнее, из-за условий, которые избегают наших знаний :).
Можно ли заставить экземпляр быть javassist proxy? Что было бы хорошей стратегией для подобных проблем в целом?
Yo ucan использует динамическую сторону groovy и объявляет Object вместо Car в вашем коде. Во время выполнения метод будет найден на экземпляре прокси, и все будет хорошо. – MatRt
Изменение подписи моего метода из-за ограничений тестирования не очень хорошо для меня: -/ – Deigote