2017-09-18 2 views
0

J'essaie de tester un service dans mon module qui dépend des services d'un autre module. Les services, composants ... de l'autre module sont accessibles via des paquets npm. Mon entreprise, comme la plupart, est un peu méticuleuse à l'idée de mettre du code source sur le web, donc j'espère que j'ai posté assez pour obtenir de l'aide.Angulaire 2 - Comment contourner une dépendance dans un autre module pour tester

Le service que je veux mocker reçoit les informations utilisateur et existe dans un autre module. J'obtiens une erreur indiquant qu'une propriété renvoyée par ce service est indéfinie. J'ai essayé d'utiliser TestBed.overrideModule pour remplacer le fournisseur de l'autre module par une version simulée que j'ai créée. J'ai du mal à trouver de la documentation pour overrideModule et j'ai essayé pendant quelques jours maintenant et ne peux pas comprendre comment faire ce que je veux travailler, même après avoir trouvé quelques utilisations de overrideModules. Toute aide serait appréciée. En fonction de l'erreur que je reçois, je me demande si la dépendance correcte est injectée mais ne sait pas vraiment comment vérifier. La trace de la pile d'erreurs pointe vers l'équivalent de webpack: ///node_modules/@another-repo/prefs/index.js.

code

(s'il vous plaît laissez-moi savoir si vous avez des questions j'ai essayé de dépouiller les choses qui identifieraient mon entreprise):

Les éléments suivants sont dans mon module

// classa.service.ts 
import { Injectable } from '@angular/core'; 
import { IDModel } from '@another-repo/core'; 
import { FormatService } from '@another-repo/prefs'; 
import { MyRepo } from './my-repo.service'; 

@Injectable() 
export class ClassA { 
    constructor(idModel: IDModel, repo: MyRepo, formats: FormatService) { 

    } 
    doSomething() { } 
} 
// in my module 
// my-repo.service.ts 
import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 

@Injectable() 
export class MyRepo { 
    constructor(private readonly http: Http) { 
    } 

    get(id): Observable<any> { 
     return this.http 
      .get(api(`${id}`)) 
      .map(response => response.json()); 
    } 
} 

// my-repo-service.spec.ts 
//... 
describe('test',() => { 
    let testService; 
    beforeEach(async() => { 
     TestBed.configureTestingModule({ 
      imports: [ 
       HttpModule, 
       FooModule 
      ], 
      providers: [ 
       { provide: RepoToMock1, useClass: MockRepoToMock1 }, 
       MyRepo, 
      ], 
     }); 

     TestBed.overrideModule(FooModule, 
      { 
       remove: { 
        providers: [RepoToMock1] 
       }, 
       add: { 
        providers: [{ provide: RepoToMock1, useClass: MockRepoToMock1 }] 
       } 
      }); 
    }); 

    beforeEach(() => { 
     testService = TestBed.get(MyRepo); 
    }); 
    //... 
}); 

c'est le fichier index.d.ts dans node_modules appelons le module FooModule

export class IDModel { 
    id: Observable<number>; 
    constructor(otherIdRepo: OtherIdRepo, otherType: OtherTypeModel); 
} 

export class FormatService { 
    constructor(formatModel: FormatModel, timeService: TimeService, numberService, NumberService); 
} 

export class FormatModel { 
    myFormat: Format; 
    constructor(repo: RepoToMock1); 
} 

export class Format { 
    branding: string; 
} 

export class RepoToMock1 { 
    constructor(http: Http); 
    getPrefs(): Observable<Format>; 
} 

export class TimeService { 
    constructor(formatModel: FormatModel); 
} 

export class NumberService { 
    getNumber(); 
} 

Répondre

0

J'utilise useFactory. Voir le code ci-dessous. En guise de remarque, j'ai trouvé que dans le test, toutes les dépendances doivent être raillées pour l'injection. Ceci découpe la base de code et permet des mises à jour des injectables sans impact sur les tests des éléments dépendants de l'injectable. Par exemple, si vous deviez injecter du service X dans les tests du composant Y sans le railler, vous avez décidé que X service avait besoin d'une nouvelle fonction qui nécessitait l'utilisation de lodash. Tous les tests du composant Y commenceraient à échouer car vous avez introduit une nouvelle dépendance et ne l'avez pas prise en compte. Les tests du composant Y échoueront, que vous utilisiez ou non la nouvelle fonction dépendante de lodash.

Si le service X a été raillé dans les tests du composant Y, toute modification peut être apportée au service X sans impact sur les tests du composant Y.

//y.component.spec.ts 
describe('YComponent',() => { 

    let component: YComponent; 
    let fixture: ComponentFixture<YComponent>; 
    let xService: XService; 

    beforeEach(async(() => { 
    let mockXService = { 
     getTextColor:() => {} 
    }; 

    TestBed.configureTestingModule({ 
     declarations: [ 
     YComponent, 
     ], 
     imports: [ 
     FormsModule 
     ], 
     providers: [ 
     {provide: XService, useFactory:() => { return mockXService; }} 
     ], 
     schemas: [CUSTOM_ELEMENTS_SCHEMA] 
    }).compileComponents(); 

    fixture = TestBed.createComponent(YComponent); 
    component = fixture.componentInstance; 
    roomingService = TestBed.get(XService); 

    fixture.detectChanges(); 
    })); 

    it('should create', async(() => { 
    // Assert 
    expect(component).toBeTruthy(); 
    })); 

}); 
+0

Je vais essayer ça aujourd'hui et rapporter ici si ça marche pour moi. Par curiosité, quel est l'avantage d'utiliser une usine? – user2157249

+0

Malheureusement, le passage à une usine n'a pas aidé à se moquer de la dépendance dans le module – user2157249