2017-04-25 1 views
0

Je n'arrive pas à trouver la bonne solution pour tester des services avec d'autres services en tant que dépendances. Le service que je suis en train de tester appelle une méthode getter sur un autre service qui renvoie une liste de tâches. C'est le service que je teste:Services de test avec des dépendances de service

Testing Service:

export class TasksData { 
    public tasks = []; 
    public tasksData = [ 
    { 
     'form': 'setup-device', 
     'type': 'register-device', 
     'text': 'Register Device', 
     'icon': 'mdi-cellphone-link', 
     'status': '' 
    }, 
    { 
     'form': 'setup-eula', 
     'type': 'confirm-eula', 
     'text': 'Agree to EULA', 
     'icon': 'mdi-pen', 
     'status': '' 
    }, 
    { 
     'form': 'setup-change-password', 
     'type': 'change-password', 
     'text': 'Change Password', 
     'icon': 'mdi-lock-reset', 
     'status': '' 
    }, 
    { 
     'form': 'setup-profile', 
     'type': 'register-profile', 
     'text': 'Register Profile', 
     'icon': 'mdi-account-plus', 
     'status': '' 
    } 
    ]; 

    constructor(private setupManager: SetupManagerService) {} 

    public getter() { 
    let data = []; 
    this.tasks = this.setupManager.getter(); 

    data = this.tasksData.filter((task) => { 
     return (this.tasks.indexOf(task.type)) !== -1; 
    }); 

    return data; 
    } 
} 

service Dépendance:

export class SetupManagerService { 
    private message: string; 
    private redirect = ''; 
    private tasks: any = []; 
    private clone: any = []; 
    private user: Object = {}; 

    public taskChange = new Subject(); 

    constructor(
    private closeModal: CloseModalService, 
    private pubsub: Pubsub, 
    private reloadStatus: ReloadStatusService, 
    private router: Router, 
    private storage: HTML5Storage 
) {} 

    // ===== Removed code for brevity ===== // 

    public getter() { 
    return this.clone; 
    } 
} 

Test:

import { TestBed } from '@angular/core/testing'; 

// Test Case: 
import { TasksData } from '../tasks-data.service'; 

// Dependencies: 
import { SetupManagerService } from '../setup-manager.service'; 

let ds = [{ 
    'form': 'setup-device', 
    'type': 'register-device', 
    'text': 'Register Device', 
    'icon': 'mdi-cellphone-link', 
    'status': '' 
}]; 

class SetupManagerServiceStub { 
    getter() { 
    return ['register-device']; 
    } 
} 

fdescribe('Service TaskData',() => { 
    let subject = TasksData; 
    let setupManager; 

    beforeEach(() => { 
    TestBed.configureTestingModule({ 
     providers: [ 
     TasksData, 
     { provide: SetupManagerService, useClass: SetupManagerServiceStub } 
     ] 
    }); 

    subject = TestBed.get(TasksData); 
    setupManager = TestBed.get(SetupManagerService); 
    }); 

    it('should create an instance',() => { 
    expect(subject).toBeDefined(); 
    }); 

    it('should... ',() => { 
    expect(subject.getter()).toEqual(ds); 
    }); 
}); 

J'ai essayé beaucoup de différents exemples de la façon de le faire en ligne, mais la plupart d'entre eux ne fonctionnent pas, probablement parce qu'ils ne sont plus valables en raison des changements de Angulaire avant la version finale.

Le service TasksData a SetupManagerService comme dépendance. Donc, pour éviter d'avoir à ajouter toutes les dépendances de SetupManagerService, j'ai créé une classe stub avec la méthode getter et je suis revenu à la valeur attendue nécessaire pour tester le service TaskData. Tout d'abord, je ne suis pas sûr si c'est même la bonne façon de le faire. Test Docs d'Angular n'ont aucun exemple de la façon de tester des services avec des dépendances de service en utilisant le module TestBed. C'est mon meilleur résultat de travail d'une journée entière d'essayer.

Ma question de savoir si c'est correct ou non n'est qu'une partie de mon problème. L'autre problème est Typescript se plaint de ce que j'ai fait et je n'ai pas trouvé un moyen de résoudre ce problème.

Même si des tests passent, je reçois l'erreur suivante:

enter image description here

Et cet avertissement soulignement rouge laid dans mon éditeur:

enter image description here

+2

commentaire assez drôle. Je suis assez sûr que la plupart des développeurs apprennent à utiliser un framework en lisant des docs. Comme je l'ai dit plus haut, tester des services avec des dépendances de service en utilisant TestBed n'était pas là. Si vous n'avez rien de constructif à dire peut-être rester à l'écart de ce que c'est censé être un endroit pour apprendre. – Aaron

Répondre

1

Ceci est uniquement un problème dactylographiée, plus précisément cette ligne:

let subject = TasksData; 

Il n'y a pas de bonne raison pour laquelle subject (qui est censé être une instance de TasksData) peuvent être attribués au constructeur. Si subject ne sera pas réaffecté pour une raison quelconque, il ne sera pas undefined, mais il ne sera pas encore une instance. Cela entraînera des tests plus difficiles à déboguer.

Ici subject est typée implicitement par valeur attribuée, il est le même que

let subject: typeof TasksData = TasksData; 

Réaffectation avec

subject = new TasksData(); 

entraînerait une erreur de type qui indique clairement ce qui ne va pas,

Type 'TasksData' is not assignable to type 'typeof TasksData'.

Mais depuis TestBed.get isn't type safe and returns any, il ne déclenche pas d'erreur de type a Et il devient évident que les types ont été foirés seulement quand subject.getter est accédé.

Il devrait être

let subject: TasksData; 
+0

Merci. Cela l'a certainement corrigé. J'apprécie cela. – Aaron

+0

De rien. – estus