web-dev-qa-db-fra.com

Spec n'a aucune attente - Jasmine teste la fonction de rappel

J'ai une méthode qui est appelée à l'aide d'un d3 timer. Chaque fois que la méthode est appelée, la méthode émet un objet avec quelques valeurs. L'une des valeurs augmente avec le temps. Je voudrais écrire un test pour vérifier si les valeurs sont dans l'ordre croissant ou non (c'est-à-dire qu'elles augmentent ou non avec le temps).

Donc, pour résoudre ce problème, dans mon test, je m'abonne à l'émetteur d'événement et à l'intérieur de l'abonnement, je pousse l'objet que je reçois dans un tableau local. Et puis, j'attends le array[i] inférieur à array[i+1]. Je pense que ma logique est parfaitement correcte mais je ne sais pas pourquoi je reçois une erreur de Jasmine disant que the spec has no expectations même si j'en ai un.

Voici le code:

let x = d3.timer((elapsed) => { 
    this.method(); // call the function
    if(elapsed >= 500) {
     x.stop(); // stops the timer.
    }
});

method(elapsed) {
 // do something
 if(elapsed > 500) {
   this.output.emit({x: somevalue, y: somevalue, f: increasingvalue });
 }
}

La spécification de jasmin:

it('my spec', inject([JumpService], (service: JumpService) =>{
  array = [];
  //service calls the method
  service.output.subscribe(e => {
   array.Push(e);
   // A console statement here will give me the length and the object pushed.
   for(let i = 0; i< array.length - 1; i++) {
    expect(array[i].f).toBeLessThan(array[i+1].f);
   }

  });

}));

Suis-je en train de faire quelque chose de mal ici? Comment puis-je aborder ce genre de scénario? Veuillez me guider dans la bonne direction.

Je vous remercie.

19
zelda

En général, lors du test des fonctions de rappel asynchrone, il est toujours important d'attendre les sorties du test une fois les promesses résolues. Vous pouvez utiliser le Angular framework de banc d'essai tick() avec le fakeAsync() ou vous pouvez simplement revenir à la façon générale du Jasmine de tester les méthodes asynchrones en utilisant done()

Utilisation de done():

it('my spec', (done) => {
  array = [];
  service.output.subscribe(e => {
   array.Push(e);
   for(let i = 0; i< array.length - 1; i++) {
    expect(array[i].f).toBeLessThan(array[i+1].f);
   }
   done();
  });
});

J'espère que cette réponse vous aidera.

Remarque: Je n'ai pas eu beaucoup de chance avec la fakeAsync() et tick(), donc je ne l'inclus pas dans la réponse. Désolé pour ça.

11
ShellZero

Essayez d'utiliser la fonction async de @angular/core/testing. Il

Enveloppe une fonction de test dans une zone de test asynchrone. Le test se terminera automatiquement lorsque tous les appels asynchrones dans cette zone seront effectués. Peut être utilisé pour encapsuler un appel {@link inject}.

Veuillez trouver l'exemple de code ci-dessous:

it('...', async(inject([AClass], (object) => {
  object.doSomething.then(() => {
   expect(...);
  })
});
9
Aliaksei Maniuk

Vous devez utiliser done () à la fin de la promesse, mais à partir de Jasmine 2.8.0 cela ne fonctionnera pas car il n'y a pas d'implémentation pour une méthode done (). Vous devriez tester vos promesses comme:

it('does test promise',
    inject([MyService], async (myService: MyService) => {
        const result = await myService.serviceToTest()
        expect(result).not.toBeNull()
        expect(result).toBe('Some Value')
     })
)

J'espère que cela vous aidera

1
Cristian Zumelzu