2017-06-16 4 views
0

Je crée un test unitaire simple pour un service qui a une dépendance. C'est un service simple que je commence à aider à comprendre le meilleur processus et la meilleure structure.Service de test unitaire avec dépendance injectée utilisant Angular 2

Le test unitaire que j'ai créé fonctionne mais TypeScript renvoie une erreur.

Argument of type '{ order_id: string; user: string; }' is not assignable to parameter of type 'Expected<Observable<any>>'. 
Object literal may only specify known properties, and 'order_id' does not exist in type 'Expected<Observable<any>>'. 

Le service exécute la méthode sendBody sur le service injecté qui effectue une requête HTTP. Je comprends qu'un Observable devrait être renvoyé ici mais j'aurais pensé que le service de simulation aurait dû résoudre cette erreur de type TypeScript.

Existe-t-il un meilleur moyen d'injecter et de fausser les dépendances lors du test de services uniquement?

service

export class ReturnOrderService { 

    constructor(private _ReturnOrderResource: ReturnOrderResource) { } 

    updateOrderStatus(orderId: string, user: string) { 
     let body = {}; 

     if (orderId !== undefined && user !== undefined) { 
      body["order_id"] = orderId; 
      body["user"] = user; 
     } 

     return this._ReturnOrderResource.sendBody(body); 
    } 

} 

Spec

const MockReturnOrderResource = { 
sendBody: function(body) { 
    return body; 
    } 
} 

describe('ReturnsComponent',() => { 

    beforeEach(() => { 
    TestBed.configureTestingModule({ providers: [ 
     ReturnOrderService, 
     { provide: ReturnOrderResource, useValue: MockReturnOrderResource } 
     ] }); 
    }); 

    it('#updateOrderStatus should create an object literal from arguments', 
    async(inject([ReturnOrderService], (service: ReturnOrderService) => { 
     expect(service.updateOrderStatus("10006886","Mr Bungle")).toEqual({ order_id: '10006886', user: 'Mr Bungle' }); 
    }))); 

}); 
+0

qu'est-ce que '_ReturnOrderResource.sendBody' retour? Pouvez-vous ajouter ce code aussi? – sabithpocker

+0

@sabithpocker il est passé à travers quelques services différents mais essentiellement fait juste une requête POST en utilisant la classe HTTP 2 Angulaire et la méthode Request: https://angular.io/api/http/Http#request. Donc, un Observable devrait être retourné – bmd

Répondre

0

J'ai travaillé dans une solution pour cela en utilisant une approche différente. Bien qu'il ne puisse pas résoudre l'erreur de type que j'éprouvais, cela me permet d'espionner le service injecté qui est exactement ce que je recherchais. Après l'injection du service, j'obtiens le service en utilisant TestBed.get() et j'attribue cela à une variable.

Je peux alors espionner le service injecté et tester le ou les arguments avec lesquels la méthode a été appelée.

La spécification mise à jour ci-dessous.

const MockReturnOrderResource = { 
    sendBody: function(body) { 
    return body; 
    } 
} 

describe('ReturnsComponent',() => { 
    let _ReturnOrderResource; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ providers: [ 
     ReturnOrderService, 
     { provide: ReturnOrderResource, useValue: MockReturnOrderResource } 
     ] }); 
    _ReturnOrderResource = TestBed.get(ReturnOrderResource); 
    }); 

    it('#updateOrderStatus should pass an object literal as an argument', 
    async(inject([ReturnOrderService], (service: ReturnOrderService) => { 
    spyOn(service, "updateOrderStatus").and.callThrough(); 
    spyOn(_ReturnOrderResource, "sendBody").and.callThrough(); 
    service.updateOrderStatus("10006886","Mr Bungle"); 
    expect(_ReturnOrderResource.sendBody).toHaveBeenCalledWith({ order_id: '10006886', user: 'Mr Bungle' }) 
    }))); 

}); 

Pour une lecture plus autour de cette solution: https://angular.io/guide/testing#testbedget

0

Si elle doit retourner un Observable, puis retourner un Observable!

Essayez ceci:

const MockReturnOrderResource = { 
    sendBody: (any: any) => Observable.of(any); 
} 
+0

Merci, trichetriche. J'ai essayé quelque chose de similaire (et maintenant ci-dessus) mais j'ai continué à avoir le même type d'erreur. Bien que le test lui-même passe dans chaque cas, ce qui est étrange. – bmd

+0

Vous erreur est que quelque part, vous attendiez un paramètre de type 'attendu >' mais vous avez fourni un objet personnalisé. Je vous suggère de trouver cette erreur et vous devriez être capable de supprimer cette erreur. – trichetriche

+0

Merci encore pour votre aide. J'ai été capable de trouver une solution en utilisant une méthode différente pour obtenir le service injecté et créer un test contre cela. J'ai inclus la réponse dans ce fil – bmd