Grails v3.3.9 - влияет на live / dev и интеграционный тест
Мой сценарий состоит в том, что у меня был интеграционный тест, который продолжал давать сбой при создании записи, созданной вручную, и одной, найденной в БД, но работает, если вы связываетедве записи, созданные вручную в тесте.
Я пробовал тысячу твиков и убедился, что GORM делал то, что было сказано в документах.
Я сократил код и что-то построилболее простой, который выглядит структурно как мой реальный материал, но основан на модели Аэропорт / Полеты в руководстве пользователя GORM (см. раздел 5.1.2 в руководстве пользователя )
Объявите абстрактный базовый класс следующим образом
Airport.groovy
abstract class Airport{
String name
Collection<? extends Flight> outboundFlights = []
Collection<? extends Flight> inboundFlights = []
static hasMany = [outboundFlights:Flight, inboundFlights:Flight]
static mappedBy = [outboundFlights: 'departureAirport', inboundFlights: 'arrivalAirport']
static constraints = {
outboundFlights nullable:true
inboundFlights nullable:true
}
static mapping = {
tablePerHierarchy false //multiple tables+joins
}
}
Объявите конкретный класс, расширяющий этот класс, который вы можете использовать:
UkAirport.groovy
class UkAirport extends Airport {
String shortCode = "dont know"
static constraints = {
}
}
Объявите объект Flight с двумя свойствами одного и того же типа
class Flight<A extends Airport> {
String flightCode = "unassigned"
A departureAirport
A arrivalAirport
//setup belongs to
static belongsTo = [departureAirport:Airport, arrivalAirport:Airport]
static constraints = {
}
}
Теперь вот интеграционный тест;есть пара вещей, на которые стоит обратить внимание.
1) Я предварительно создаю UkAirport в настройке (для него не заявлено ни одного рейса) 2) Я создаю два ручных UkAirports в настоящем тесте - Gatwick и Stansted и сохраняю эти 3) Iустановить два рейса - один из Гатвика в Станстед и рейс 2 из Гатвика в предварительно спасенный Манчестер, который я нахожу, выполняя UkAirport.get ()
Вот странная вещь.Если я проведу этот тест, как показано здесь, - он пройдет, потому что я утверждаю, что в Манчестер не существует никаких рейсов (assert manchester.inboundFlights.size() == 0
).
Однако, если вы прокомментируете это утверждение, и повторите тест,потерпит неудачу, и он объявит, что manchester.inboundFlights.size()
равно 2 -
То же самое, если я использую отладчик - если остановиться и посмотреть на Манчестер до того, как я выполню flight2.save (), тест будет работать -если вы установите точку останова после flight2.save (), то manchester.inboundFlights покажет 2 записи, что неверно.
class AirportIntegrationSpec extends Specification {
def setup() {
Airport manchester = new UkAirport (name:"Manchester", shortCode:"MAN")
manchester.save(failOnError:true)
}
def cleanup() {
}
void "two airports and one flight "() {
given :
Airport gatwick = new UkAirport (name:"Gatwick", shortCode:"LGW")
Airport stansted = new UkAirport (name:"Stansted", shortCode:"STN")
Airport manchester = UkAirport.get(1L)
assert manchester.shortCode == "MAN"
gatwick.save ()
stansted.save ()
when:
Flight flight = new Flight<UkAirport>(flightCode:"F123-LGW-STN")
gatwick.addToOutboundFlights(flight)
stansted.addToInboundFlights(flight)
flight.save (failOnError:true)
assert gatwick.outboundFlights.size() == 1
assert gatwick.inboundFlights.size() == 0
assert stansted.outboundFlights.size() == 0
assert stansted.inboundFlights.size() == 1
// -all ok until we get to here - if you evaluate manchester before you use it - test works
//if you comment out and use before you evaluate it fails !
assert manchester.inboundFlights.size() == 0 //comment out makes test fail !
Flight flight2 = new Flight<UkAirport>(flightCode:"F789-LGW-MAN")
gatwick.addToOutboundFlights(flight2)
manchester.addToInboundFlights(flight2)
flight2.save (failOnError:true)
assert gatwick.outboundFlights.size() == 2
assert manchester.inboundFlights.size() == 1
then :""
flight.id == 1
flight2.id == 2
gatwick.inboundFlights.size() == 0
gatwick.outboundFlights.size() == 2
stansted.outboundFlights.size() == 0
stansted.inboundFlights.size() == 1
flight.departureAirport.name == "Gatwick"
flight.arrivalAirport.name == "Stansted"
flight2.departureAirport.name == "Gatwick"
flight2.arrivalAirport.name == "Manchester"
}
}
Может ли кто-нибудь подтвердить, что это действительно дефект, и я его исправлю (временное обходное решение в коде - это доступ к сущности, выбранной из БД, - прежде чем вы затем построите какие-либо отношения вокругэто).
Мой проект Github здесь и интеграционный тест для всех это здесь .
Это мой предыдущий связанный стекВопрос переполнения - который я обновлю, так как он сводится к вышеприведенному.