2015-07-04 11 views
5

Za pomocą prostego testu integracji spocku z kontrolerem czynności. Oto mój test.Błąd testowania integracji kontrolera Grails3: Nie znaleziono żądania związanego z wątkiem

@Integration 
@Rollback 
class TestControllerSpec extends Specification { 

    def setup() { 
    } 

    def cleanup() { 
    } 

    void "test something"() { 
     setup: 
     def c = new TestController() 
     c.index() 
     expect: 
     c.response.contentType !=null 
    } 
} 

się następujący wyjątek

java.lang.IllegalStateException: No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request. 
    at org.springframework.web.context.request.RequestContextHolder.currentRequestAttributes(RequestContextHolder.java:131) 
    at grails.web.api.WebAttributes$Trait$Helper.currentRequestAttributes(WebAttributes.groovy:45) 
    at grails.web.api.ServletAttributes$Trait$Helper.getRequest(ServletAttributes.groovy:42) 
+0

Można dodać pełną rzeczywistą klasę testową i kontrolowany kontroler do q również ujęcie? – dmahapatro

+0

@dmahapatro Mam zaktualizowane moje pytanie. – user1071671

Odpowiedz

4

Niestety może to być ograniczenie w Grails 3, że nie można korzystać z testów integracyjnych do sterowników testowych.

integracji sterowników go przetestować zaleca korzystania polecenie tworzenia funkcjonalnych testowej, aby stworzyć test funkcjonalny Geb.

Source from Grails documentation

To wydaje się być zasadnicza zmiana kierunku z poprzednich wersji Grails. Jeśli naprawdę trzeba przetestować kontroler w teście integracji, można spróbować w ten sposób:

UWAGA: Zdaję sobie sprawę, że to może być złą praktyką, a to jest sprzeczne z dokumentacją Grails, ale czasami trzeba także sprawdzić rzeczy bardziej programistyczne, gdzie testy jednostkowe nie są wystarczające, a testy Geb nie są wystarczająco szczegółowe.

@TestFor(TestController) // This will provide a mocked "controller" reference 
@Integration 
@Rollback 
class TestControllerSpec extends Specification { 

    // If TestController uses any services, have them autowired into this test 
    @Autowired 
    SomeService someService 

    def setupSpec() { 
     // Now connect those services to the controller 
     controller.someService = someService 
    } 

    void "test something"() { 
     when: 
     controller.index() 

     then: 
     response.contentType != null 
    } 
} 

UWAGA: Po pewnym dodatkowej pracy z tego formatu znalazłem problem. Użycie @TestFor wywoła Holders.clear() po zakończeniu, co oznacza, że ​​nie będzie obiektu grailsApplication w Holders. Będzie to powodować problemy, jeśli masz jakieś testy integracyjne, które działają po tym, który używa powyższego podejścia. Po wielu kopaniu nie wygląda na to, że istnieje łatwy (lub nawet trudny) sposób wykonania tej pracy, prawdopodobnie dlatego nie jest obsługiwany w Grails 3. W związku z tym jedną z opcji jest oznaczenie innych testów integracyjnych za pomocą @TestFor, aby klasa Holders została poprawnie wypełniona. Czy to jest hack? Tak to jest! Będziesz musiał zdecydować, czy warto podjąć wysiłek dodania tego obciążenia do wszystkich testów. W moim przypadku był to tylko jeden test integracyjny, który tego wymagał (ponieważ jest to mała aplikacja), ale gdyby było więcej, nie użyłbym tego podejścia.

9

Robiłem to i wydaje się działać prawidłowo:

Dodaj pole:

@Autowired 
WebApplicationContext ctx 

W setup(): GrailsWebMockUtil.bindMockWebRequest(ctx)

W cleanup(): RequestContextHolder.resetRequestAttributes()

Powiązane problemy