2016-03-29 18 views
2

Ich bin sehr neu in Spock und ich habe kein Beispiel gefunden, was ich brauche, also denke ich, der beste Weg ist, Beispiel zu zeigen, was ich haben muss.Spock - spotting externen Service

  1. z.B. Testklasse in spock:

    def "getData"(){ // this is test of getData method from ExternalService 
        when: 
        Result result = externalService.getData() 
        then: 
        result.msg = 'SUCCESS' 
    } 
    
  2. Klasse:

    public class ExternalService(){ 
        private ServiceConnector serviceConnector; 
    
        public Result getData(){ 
        Result result = serviceConnector.callAndGet(); 
        prepareInformation(data); 
        updateStatuses(data); 
        return result; 
        } 
    } 
    
  3. Klassendaten:

    public class Data{ 
        private String msg; 
        private int Id; 
        // +getters/setters 
    } 
    

Und jetzt sind getData Test und möchte nur Methode verspotten callAndGet() . Es bedeutet, dass jedes Mal, wenn ich callAndGet rufe, ich Objektdaten mit msg SUCCESS haben muss, aber alle anderen Methoden von getData Methode sollte normalerweise aufgerufen werden.

Ist es verständlich? Kannst du mir helfen?

Antwort

7

Was Sie tun müssen, ist die ServiceConnector Klasse zu verspotten und es über Konstruktor übergeben (z). Siehe unten:

@Grab('org.spockframework:spock-core:1.0-groovy-2.4') 
@Grab('cglib:cglib-nodep:3.1') 


import spock.lang.* 

class Test extends Specification { 
    def 'some spec'() { 
     given:  
      def serviceConnector = Mock(ServiceConnector) { 
       callAndGet() >> new Result(msg: 'SUCCESS') 
      } 
      def externalService = new ExternalService(serviceConnector) 

     when: 
      Result result = externalService.getData() 

     then: 
      result.msg == 'SUCCESS' 
    } 
} 

public class ExternalService { 
    private ServiceConnector serviceConnector 

    public ExternalService(ServiceConnector serviceConnector) { 
     this.serviceConnector = serviceConnector 
    } 

    public Result getData() { 
    Result result = serviceConnector.callAndGet() 

    prepareInformation(result) 
    updateStatuses(result) 
    result 
    } 

    private void prepareInformation(Result data) { 
    } 

    private void updateStatuses(Result data) { 
    } 
} 

public class ServiceConnector { 
    public Result callAndGet() { 

    }  
} 

public class Result { 
    String msg 
} 
2

Sie sollten nicht versuchen, "nur eine Methode" Ihrer Dienste zu verspotten. Es ist nur ein Zeichen für ein schlechtes Design, Ihr Code ist nicht testbar. Sie sollten die Abhängigkeiten Ihrer Klasse mit kleinen Diensten isolieren und diese Dienste in einem Komponententest vortäuschen. Testen Sie dann die obere Schicht mit einem Integrationstest und einer vollständigen Implementierung Ihrer Abhängigkeiten.

In Ihrem Beispiel ServiceConnector sollte eine Schnittstelle sein, die leicht verspottet werden können.

def "test a mocked service connector"() { 
    given: "a service connector" 
    def serviceConnector = Mock(ServiceConnector) 

and: "an external service" 
    def externalService = new ExternalService(serviceConnector:serviceConnector) 

when: "Data is loaded" 
    def result = externalService.data 

then: "ServiceConnector is called" 
    serviceConnector.callAndGet() >> new Result(msg:"SUCCESS") 

and: "Data is mocked" 
    result.msg == "SUCCESS" 
} 

Wenn jedoch ServiceConnector eine Klasse ist und Sie können dies nicht ändern, können Sie einen Teil Mock in Spock verwenden können: Mit dieser Bedingung kann der Test als geschrieben werden. Diese Art von Test ist schwer zu halten und eine Menge Nebeneffekt hat:

def "test a mocked service connector"() { 
    given: "a service connector" 
    def serviceConnector = Spy(ServiceConnector) { 
     callAndGet() >> new Result(msg:"SUCCESS") 
    } 

and: "an external service" 
    def externalService = new ExternalService(serviceConnector:serviceConnector) 

when: "Data is loaded" 
    def result = externalService.data 

then: "Data is mocked" 
    result.msg == "SUCCESS" 
} 
Verwandte Themen