2016-07-15 9 views
1

Ich habe gerade angefangen, an Spock testing framework für Java-Anwendungen zu arbeiten. Ich habe keine Erfahrung mit Groovy. Wie injizieren wir Spock in den Konstruktor? Unten ist mein Code und Testbeispiel.Wie injizieren Mock-Objekt in den Konstruktor?

public class ResourceClass { 
    private final IDynamoDBMapper factory = new DefaultDynamoDBClientFactory(DynamoDBConfig.fromProperties()).mapperClient(); 

    private ServiceClass service; 

    @Inject 
    public ResourceClass(ServiceClass service) { 
     this.service = service; 
    } 
} 

Und ich habe versucht, Testklasse wie unten zu erstellen.

class ResourceClassTest extends Specification { 
ResourceClass eventsResource 
ServiceClass service 

def setup() { 
    service = Mock(ServiceClass) 
    eventsResource = new ResourceClass(service) 
} 

Aber ich bin immer unter Ausnahme bei eventsResource = new Resource (Service)

java.lang.NullPointerException: Domain name must be specified. 

at java.util.Objects.requireNonNull(Objects.java:228) 

Anregungen bitte?

Antwort

1

Das Problem besteht nicht darin, den Mock in den Konstruktor ResourceClass zu "injizieren", da Sie gerade den Konstruktor aufrufen, der den Schein übergibt. Der Grund dieser Ausnahme passiert ist, weil dieses Feld Erklärung + initialiazation:

private final IDynamoDBMapper factory = new DefaultDynamoDBClientFactory(DynamoDBConfig.fromProperties()).mapperClient(); 

Initialisierung der Fabrik Feld passieren wird, bevor der Konstruktor ausgeführt wird (es wird tatsächlich in den Anfang des Konstrukteurs bei der Erstellung kopiert werden).

Entweder Sie können überprüfen, warum die Initialisierung der Fabrik fehlschlägt (wie überprüfen, wie DynamoDBConfig.fromProperties() funktioniert und wo die Domäneneigenschaft für dynamo db Verbindung angegeben werden sollte) oder Sie können den Quellcode ändern, um das Factory-Objekt in die Resource-Klasse zu injizieren gleiche Art und Weise, wie Sie mit dem Service, durch den Konstruktor tun, dann im Test ein Modell von IDynamoDBMapper in den Dienst Konstruktor übergeben:

public class ResourceClass { 
    private final IDynamoDBMapper factory; 
    private ServiceClass service; 

    @Inject 
    public ResourceClass(ServiceClass service, IDynamoDBMapper factory) { 
     this.service = service; 
     this.factory = factory; 
    } 
} 

class ResourceClassTest extends Specification { 
    ResourceClass eventsResource 
    ServiceClass service 
    IDynamoDBMapper mapper 

    def setup() { 
     service = Mock(ServiceClass) 
     mapper = Mock(IDynamoDBMapper) 
     eventsResource = new ResourceClass(service, mapper) 
    } 
} 

bei der zweiten Lösung, die Sie mehr Kontrolle über die Prüfung die Ressourcenklasse, aber die erste Lösung sollte einfacher sein

+0

Sie Gergely danken. Ich änderte den Quellcode, um DynamoDBMapper in die Ressourcenklasse zu injizieren. Dies geschieht nur bei Verwendung von Spock oder mit Mockito auch? – vamsi

+0

Dies geschieht beim Ausführen der Spock-Tests, aber es ist kein Spock-Problem, aber der Klassenpfad unterscheidet sich normalerweise beim Ausführen der Anwendung und beim Ausführen der Tests. Wenn Sie die dynamo db-Konfigurationsdatei beim Ausführen der App im Klassenpfad haben, aber nicht beim Ausführen der Tests –

1

Eit Sie müssen Ihre DefaultDynamoDBClientFactory.mapperClient() irgendwie verspotten oder es injizierbar machen, sonst wird es nach echter Instanziierung suchen und scheitern.

public class ResourceClass { 
    private IDynamoDBMapper factory; 
    private ServiceClass service; 

    @Inject 
    public ResourceClass(IDynamoDBMapper factory, ServiceClass service) { 
     this.factory = factory; 
     this.service = service; 
    } 
} 

Dann sollten Sie wie unten zu Einheit testen Sie Ihre Resource auf sympatische Weise der Lage sein,

class ResourceClassSpec extends Specification { 
    ResourceClass eventsResource 

    def setup() { 
     eventsResource = new ResourceClass(factory: Mock(IDynamoDBMapper), service: Mock(ServiceClass)) 
    } 

    def 'test does something'() { 
     given: 'given x' 
      // 
     when: 'when you call some method of resourceClass' 
      // 
     then: 'what you expect' 
      // 
      1 == 2 
    } 
}