2011-08-12 9 views
6

Mamy niestandardowe źródło danych, które rozszerza BasicDataSource. Zastąpiliśmy metodę getConnection, która zawiera kilka rzeczy wewnątrz niej. Kiedy uruchamiamy aplikację webową poza testowaniem, gdy wywołujemy usługę z kontrolera, pobiera ona nowe połączenie i używa tego połączenia, dopóki usługa nie zostanie wykonana. Wszystko dobrze. Jednak w teście integracyjnym połączenie wydaje się być przechwytywane zanim test wywoła kontroler. Przepływ poniżejGrails Connections zachowuje się zupełnie inaczej w teście integracji

Regular Run: kontroler połączeń -> kontroler wywołuje metodę service -> połączenia chwycił -> Metoda serwis jest prowadzony i wraca do sterownika

test integracyjny: połączenia chwycił -> kontroler połączeń z testu -> metoda obsługi wywołań kontrolnych -> metoda serwisowa jest uruchamiana i wraca do kontrolera

Nie trzeba dodawać, że stwarza to problemy, ponieważ właściwe połączenie jest bardzo ważne dla naszej aplikacji. Myśli?

Edycja: Nadal występują istotne problemy z tym. Doszliśmy do punktu, w którym mamy do uniknięcia tworzenia testów integracyjnych, czy jakieś ręczne przełączanie połączenia (który pokonał pół punktu testów)

DataSource.groovy

dataSource { 
pooled = true 
dialect="org.hibernate.dialect.OracleDialect" 
properties { 
    maxActive = 50 
    maxIdle = 10 
    initialSize = 10 
    minEvictableIdleTimeMillis = 1800000 
    timeBetweenEvictionRunsMillis = 1800000 
    maxWait = 10000 
    testWhileIdle = true 
    numTestsPerEvictionRun = 3 
    testOnBorrow = true 
} 

} 
hibernate { 
cache.use_second_level_cache = true 
cache.use_query_cache = true 
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider' 
} 
+0

czy wdrażasz ControllerUnitTestCase? lub po prostu UnitTestCase ?! –

+0

ControllerUnitTestCase – Joseph

+0

Czy mógłbyś opublikować swój plik DataSource.groovy? –

Odpowiedz

2

To nie jest ostateczna odpowiedź, jednak wierzę, że to jest wyjaśnienie tego, co się dzieje:

  • Running jako Web app: klasa usługi ma transactionManager który ma SessionFactory, pobierającą połączenie! Tak więc w tym przypadku, zakładając, że twoja usługa jest "transakcyjna = prawdziwa", wszystkie metody, które wywołasz w twoich usługach będą miały "Session.beginTransaction()" na początku metody (jest to Proxy Grailsa, aby to zrobić , kiedy ustawisz "transakcyjne = true"), które wywoła cały stos aż do getConnection().

  • Uruchamianie jako test integracji: ponieważ Grails nie zatwierdza zmian DB, zawsze je wycofuje! Wierzę, że kiedy rozpoczynasz test integracji, grails natychmiast tworzy transakcję! więc będzie mógł je później wycofać! (co jest całkowicie sensowne!), możesz potwierdzić, że przyjrzyj się klasie org.codehaus.groovy.grails.test.support.GrailsTestInterceptor. Metoda init() jest wywoływana przed usługami w teście integracji. Właśnie dlatego getConnection() jest wywoływana przed wszystkim!

Sugestia: Można spróbować ustawić swoją klasę integracyjną testową jako „transakcji = False” i zobaczyć czy getConnection() nie dostać zadzwonić na początku! Przejdź do sekcji Transakcje w here, aby zobaczyć więcej! Nie zapomnij, że w teście będziesz musiał wycofać transakcję! jeśli twoja ustawiona transakcja = false.

+1

Zdecydowanie wypróbuję to później, kiedy dostanę czas. – Joseph

+0

Przepraszam, byłem zajęty błędami. Mam nadzieję, że będę miał czas dzisiaj :) – Joseph

+0

To wydaje się być problemem z tym, co się dzieje. Ponieważ ma już połączenie, nie próbuje pobrać nowego. Dzięki za pomoc. – Joseph