2013-03-21 9 views
8

Przepraszam, jeśli to jest pytanie dla początkujących, ale byłbym wdzięczny za wszelkie spostrzeżenia, jakie społeczność mogłaby zaoferować w związku z problemem, który mam z upuszczaniem następującej metody, którą mieć w usłudze Grails, LocationService.Używanie Spocka do odgadnięcia Gorma i innych metod w domenie z domeną Grails

Mam klasę domenową, Żądanie, że oprócz domyślnych metod GORM ma również pewne dodatkowe metody domenowe, np. metoda create() poniżej

@EqualsAndHashCode 
class Request { 

    String reference 
    String msid 
    Type type 
    Status status 
    Destination destination 
    DateTime dateCreated 
    DateTime dateCompleted 

    static create(String msid, Type type, Destination destination = Destination.DEFAULT) { 
      new Request(reference: reference(type), type: type, status: Status.INITIATED, dateCreated: new DateTime()) 
    } 

Wreszcie mam specyfikację Spock. Muszę wyśmiać zarówno domyślne metody GORM, jak i niektóre niektóre dodatkowe logiki domeny, np. Statyczną metodę tworzenia, w celu zwrócenia poprawnego obiektu, który ma być utrwalony w testowanym kodzie.

Idealnie, użyłbym Spocków, ale nie mogę ich tutaj użyć, ponieważ zgodnie z postem poniżej od Petera N, muszą zostać wstrzyknięte do dzwoniącego, a w tym przypadku do Zapytania (które próbuję naśladować)), jest tworzony jako zmiennej lokalnej w sposób zlokalizować w LocationService:

https://groups.google.com/forum/?fromgroups=#!topic/spockframework/JemiKvUiBdo

Nie mogę korzystać z Grails 2.x @Mock adnotacji jak, chociaż będzie to mock metod Gorm, jestem pewien, czy Mogę symulować/stosować dodatkowe statyczne metody create() z klasy Request.

W związku z tym, próbowałem użyć metod Groovy StubFor/MockFor, aby to zrobić, ponieważ uważam, że zostaną one użyte w wywołaniu metody testowej przez zawinięcie go w zamknięciu użycia (jak poniżej).

Oto spec testu:

@TestFor(LocationService) 
// @Mock(Request) 
class LocationServiceSpec extends Specification { 

    @Shared app = "TEST_APP" 
    @Shared target = "123" 
    @Shared locator = "999" 

    def locationService = new LocationService() 
    LocationSource locationSource = Mock() 


    def "locating a valid target should default to locating a target synchronously"() { 
     given: 
      def stub = new StubFor(Request) 
      stub.demand.create { target, type -> new Request(msid: target, type: type) } 
      stub.demand.save { true } 
      1 * locationSource.locateTarget(target, locator, app, SYNC) >> { Location.create(target, point, cellId, lac) } 
      def location 
     when: 
      stub.use { 
       location = locationService.locate(target, locator, app) 
      } 
     then: 
      location 
} 

Jednak, kiedy uruchomić test, chociaż zgaszone stworzyć metodę zwraca moją prośbę obiekt stub, mam awarię na zgaszone Zapisz metody:

groovy.lang.MissingMethodException: No signature of method:  com.domain.Request.save() is applicable for argument types:() values: [] 
Possible solutions: save(), save(boolean), save(java.util.Map), wait(), last(), any() 

Ktoś może wskazać, co robię źle tutaj lub sugerować najlepsze podejście do rozwiązania mojej konkretnej sprawy, jeśli potrzeba dodatkowych metod dodatkowych, a także metod GORM klasy domeny, których nie mogę wstrzyknąć bezpośrednio do kodu pod test?

Dziękuję z góry,

Patricka

Odpowiedz

8

Uważam, że powinniśmy być w stanie używać Grails' @Mock adnotacji jak wspomniałeś o metodach Gorm, a następnie trzeba będzie ręcznie mock metod statycznych:

@TestFor(LocationService) 
@Mock(Request)// This will mock the GORM methods, as you suggested 
class LocationServiceSpec extends Specification { 
... 
    void setup() { 
     Request.metaClass.static.create = { String msid, Type type, Destination destination = Destination.DEFAULT -> 
      //Some logic here 
     } 
    } 
... 

Podczas korzystania z @Mock adnotacji, Grails będą drwić metody domyślne (zapisać/get/dynamiczne dystansu), ale to nie robi nic, aby żadnych dodatkowych metod możesz zostały dodane, więc trzeba manu sojusznik kpi z nich.

+0

Dziękuję GrailsGuy. To rozwiązało mój problem. Byłem coraz trudniejszy do pogodzenia się z używaniem '@ Mock', aby kpić z domyślnych metod i jak ręcznie nadpisywać dodatkowe metody. Używanie '@ Mock' dało mi to pierwsze, ale nie drugie. I użycie StubFor dało mi to drugie, ale nie pierwsze. Ale nie wydawali się działać w połączeniu. Jednak użycie '@ Mock' na poprzednim i modyfikowanie metaClass, aby uzyskać to drugie rozwiązanie, doskonale rozwiązuje problem. Wielkie dzięki. – Paddy

+1

@Paddy Nie ma problemu, cieszę się, że mogę pomóc! – Igor

+1

@Igor Powinien to być "Request.metaClass.static.create ..." To właśnie dla mnie zadziałało! – Champ

Powiązane problemy