2017-09-02 4 views
0

Ello tous, donc j'ai essayé d'écrire un test unitaire qui attend un certain type d'exception. J'ai eu une fonction qui a jeté cette exception, mais j'ai encore un test qui échoue. Pour résoudre le problème, je suis allé aussi loin que d'essayer de lancer la même exception et d'avoir un échec. Je peux le faire passer en comparant le message mais, cela semble être une idée terrible.Chai s'attendre à lancer Exception ne correspondant pas à la même exception en utilisant Typescript

Comment dois-je gérer les tests pour une exception personnalisée correspondante?

Code de classe

export class EventEntity { 

    comments : Array<string> = new Array<string>(); 

    constructor() {} 

    public addComment(comment : string) { 
     this.comments.push(comment); 
    } 

    public getCommentCount() : number { 
     return this.comments.length; 
    } 

    public getCommentByOrder(commentNumber : number) : string { 
     console.log(`getCommentByOrder with arg:${commentNumber}`);    

     let offset = 1; 
     try { 
      let result = this.comments[commentNumber - offset]; 
      return result; 
     } catch (err){ 
       console.log(`getCommentByOrder:Error: ${err.toString()}`); 
      console.log(`err: with arg:${commentNumber}`); 
      if(err instanceof RangeError){ 
       throw new CommentNotFoundException(); 
      } 
      throw err; 
     } 
    } 
} 

MyException

export class CommentNotFoundException extends Error { 
    constructor(m?:string) 
    { 
     let message : string = m?m:"Comment number not found in event's comments.";   
     super(message); 
     Object.setPrototypeOf(this, CommentNotFoundException.prototype); 
    } 
} 

A défaut d'essai

@test shouldThrowIfCommentNumberIsGreaterThanTotalNumberOfComments() { 
    let testEvent = new EventEntity(); 
    let expectedException = new CommentNotFoundException(); 
    //expect(testEvent.getCommentByOrder(5)).to.throw(expectedException); 
    expect(()=> { 
     throw new CommentNotFoundException(); 
    }).to.throw(new CommentNotFoundException()); 
} 

mise à jour

D'accord, j'ai révisé. Cela fonctionne comme prévu. L'exception n'était pas repris sous la forme:

expect(testEvent.getCommentByOrder(5)).to.throw(CommentNotFoundException); 

mais cela ne:

expect(()=>{ 
     testEvent.getCommentByOrder(5); 
}).to.throw(CommentNotFoundException); 

Voici la liste avec le code mis à jour:

méthode

public getCommentByOrder(commentNumber : number) : string { 
    let offset = 1; 
    let result = this.comments[commentNumber - offset]; 
    if (!result) { 
     throw new CommentNotFoundException(); 
    } else { 
     return result; 
    } 
} 

test

@test shouldThrowIfCommentNumberIsGreaterThanTotalNumberOfComments() { 
    let testEvent = new EventEntity(); 
    expect(()=>{ 
      testEvent.getCommentByOrder(5); 
    }).to.throw(CommentNotFoundException); 
} 

C'est une victoire, merci!

Répondre

1

Vous transmettez une erreur instance à la méthode .throw(...). Vous devez passer un constructeur à la place. Et ce que vous passez à expect doit être une fonction que expect appellera. Votre commenté la ligne devrait être modifiée pour:

expect(() => testEvent.getCommentByOrder(5)).to.throw(CommentNotFoundException); 

Vous pouvez passer une instance à la méthode mais l'affirmation passera si et seulement si l'instance soulevée par la fonction testée et l'instance que vous passez à .throw(...) satisfaire une comparaison avec ===. En d'autres termes, les deux valeurs doivent être exactement le même objet JS. Lorsque vous testez du code réel (plutôt que des exemples triviaux), il est presque impossible que vous obteniez l'instance d'erreur avant que l'erreur ne soit déclenchée. Passer une instance est donc quelque chose que vous ne pouvez normalement pas faire.

+0

Ce n'était pas la solution exacte mais, totalement m'a mis sur la bonne voie. Je vous remercie!!! – Terrance

+0

Vous avez probablement lu ma réponse avant la [dernière modification] (https://stackoverflow.com/revisions/46018605/2). Malheureusement, SO écrase les éditions faites en succession rapprochée mais ma dernière modification consistait à changer l'argument passé à 'expect' pour en faire une fonction. J'avais d'abord saisi le problème constructeur/instance et l'ai manqué. – Louis