2013-03-06 6 views
7

Attualmente si aggiorna un'app 1.3.7 di Grails a 2.1.0 e si dispone di un set di filtri che vorrei testare. Visto che il grails documentation for testing filters suggerisce che il Test di unità per i filtri è ora supportato (/ è raccomandato? È menzionato nella parte funzionale ma non trova esempi), sto tentando di convertire alcuni test di integrazione esistenti per il filtro in test di unità.Grails 2.0 Filtri di verifica unità: servizio di iniezione e dependOn

Tuttavia, sto faticando per "deridere" correttamente un filtro questo filtro dependsOn/per lo meno correttamente implementare una simulazione per alcuni service s in cui vengono iniettati i filtri.

package com.example 

import ... // excluded for brevity 


class MyFilters { 

    GrailsApplication grailsApplication 
    SomeService someService 

    def dependsOn = [MyOtherFilters] 


    def filters = { 
     all(controller: 'controllerToExclude', invert: true) { 
      before = { 
       if (grailsApplication.config.someConfigProperty) { 
        def someProperty = request.getAttribute('MY_ATTRIBUTE') 

        if (someProperty = someService.someMethod()) { 
         redirect(url: someService.getNewUrl(session)) 
         return false 
        } 
       } 
       return true 
      } 
     } 
    } 
} 

E l'altro filtro:

package com.example 

class MyOtherFilters { 

    SomeOtherService someOtherService 

    def filters = { 
     all(controller: '*', action: '*') { 
      before = { 
       def foo 

       if (params[MY_ATTRIBUTE]) { 
        foo = params[MY_ATTRIBUTE] 
        someOtherService.setMyAttribute(sitePreference, request) 
       } 

       if (!foo) { 
        foo = someOtherService.getMyAttribute(request) 
       } 

       if (foo) { 
        request.setAttribute('MY_ATTRIBUTE', foo) 
       }  

       return true 
      } 
     } 
    } 
} 

Questa è una versione davvero scheletro semplificata dei due filtri con cui sto lavorando (se qualcuno è curioso, leggono un cellulare vs preferenze del desktop e poi filtrare basato su tale preferenza).

Quindi la prova che sto scrivendo sembra grosso modo così:

package com.example 

import grails.test.mixin.TestFor // ... etc more imports here 

@TestFor(SomeController) 
@Mock(MyFilters) // TODO what goes here??? 
class MyFiltersTests { 

    static final IPAD_USER_AGENT = 'Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X; en-us) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3' 
    static final NON_MOBILE_USER_AGENT = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:7.0.1) Gecko/20100101 Firefox/7.0.12011-10-16 20:23:00' 


    void testFilterRedirects() { 
     grailsApplication.config.someConfigProperty = true 
     // actual filter logic acts on this user-agent through some service calls, would like to mock it out though  
     request.addHeader("user-agent", IPAD_USER_AGENT) 
     def result 

     withFilters(action: "index") { 
      result = controller.index() 
     } 

     //assertSomething on result perhaps 
     assertEquals "myExpectedRedirectUrl", response.redirectedUrl 
    } 
} 

Come questo codice si trova, non ha nemmeno eseguire il codice MyFilters. Ho provato ad aggiungere i filtri dipendenti al ala beffardo:

@Mock([MyFilters, MyOtherFilters]) 

Ma poi mi imbatto in problemi con le SomeOtherService metodi non in fase di definizione, e non ho trovato un modo per prendere in giro quei metodi in modo corretto (come faccio impostare un servizio su un filtro? su un controller o un servizio è possibile def myMock = mockFor(SomeOtherService) e quindi fare controller.someOtherService = myMock.createMock() o qualcosa del genere, ma non riesco a trovare un modo per impostare il servizio per il filtro con questo blocco withFilters che la documentazione suggerisce di utilizzare

Idealmente, mi piacerebbe prendere in giro tutto ciò che ha a che fare con someService e MyOtherFilters, e semplicemente scrivendo il mio prova su questo filtro, ma non sono sicuro di cosa sia possibile con i filtri di test.

Qualsiasi intuizione sarebbe molto apprezzata, grazie mille se l'hai fatta così lontano!

risposta

2

Hanno lo stesso problema. C'è un bug cresciuto in Grails Jira http://jira.grails.org/browse/GRAILS-8976

ho trovato soluzione in http://delvingintodev.carrclan.us/2012/12/testing-grails-filters-that-use-services.html 'Filtri test Grails che utilizzano i servizi '

Che, fondamentalmente, è necessario utilizzare il servizio nel filtro come segue

package xxx.me 

class MyFilters { 
    def filters = { 
     all(controller:'*', action:'*') { 
      before = { 
       applicationContext.getBean(MyService).doSomethingClever() 
      } 
     } 
    } 
} 

In questo caso si sarà in grado di deriderlo in unit test

package xxx.me 

@TestMixin(GrailsUnitTestMixin) 
@Mock(MyFilters) 
class MyFiltersTests { 

    @Test 
    public void testFilter(){ 
     defineBeans { 
      myService(StubbedMyService) 
     } 
     SimpleController controller = mockController(SimpleController); 

     withFilters(controller:"simple" , action:"index"){ 
      controller.index()  
     } 
    } 
} 

class StubbedMyService extends MyService { 
    def doSomethingClever(){ 
    } 
} 
Problemi correlati