2012-09-22 16 views
8

Ho un file app.coffee:Mocha, should.js e affermando un'eccezione

class TaskList 

class Task 
    constructor: (@name) -> 
     @status = 'incomplete' 
    complete: -> 
     if @parent? and @parent.status isnt 'completed' 
      throw "Dependent task '#{@parent.name}' is not completed." 
     @status = 'complete' 
     true 
    dependsOn: (@parent) -> 
     @parent.child = @ 
     @status = 'dependent' 

# Prepare scope stuff 
root = exports ? window 
root.TaskList = TaskList 
root.Task = Task 

e un file denominato test/taskTest.coffee:

{TaskList, Task} = require '../app' 
should = require 'should' 

describe 'Task Instance', -> 
    task1 = task2 = null 
    it 'should have a name', -> 
     something = 'asdf' 
     something.should.equal 'asdf' 
     task1 = new Task 'feed the cat' 
     task1.name.should.equal 'feed the cat' 
    it 'should be initially incomplete', -> 
     task1.status.should.equal 'incomplete' 
    it 'should be able to be completed', -> 
     task1.complete().should.be.true 
     task1.status.should.equal 'complete' 
    it 'should be able to be dependent on another task', -> 
     task1 = new Task 'wash dishes' 
     task2 = new Task 'dry dishes' 
     task2.dependsOn task1 
     task2.status.should.equal 'dependent' 
     task2.parent.should.equal task1 
     task1.child.should.equal task2 
    it 'should refuse completion it is dependent on an uncompleted task', -> 
     (-> task2.complete()).should.throw "Dependent task 'wash dishes' is not completed." 

Se corro questo comando nel terminale: mocha -r should --compilers coffee:coffee-script -R spec Ho un test fallito (quello finale) che diceva che si aspettava un'eccezione "Lavaggio dei piatti dipendenti" non è stato completato. " ma è diventato "indefinito".

Se cambio (-> task2.complete()).should.throw a -> task2.complete().should.throw rimuovendo la parentesi, il test ha esito positivo e non riesce se non si genera l'eccezione. Ma se cambio il messaggio di eccezione in qualcosa di casuale, passa comunque. Sto facendo qualcosa di sbagliato? Non dovrebbe passare il test solo se il messaggio è letteralmente "Lavare i piatti" compito dipendente "non è completato."?

+0

sei sicuro che "lavare i piatti" è "' 'parent.name'''? Vorrei ridichiarare le proprietà in ogni fase del test. puoi usare prima di ogni altro nel tuo test. – vik

+0

@vik Sì, è 'parent.name'. Ho provato a ridichiarare ciascuna proprietà in beforeEach() e ho ancora lo stesso problema. L'asserzione finale diventa "indefinita". – Matthew

risposta

4

si sta gettando un'eccezione con una stringa invece di buttare un oggetto errore. throw() cerca il secondo. Così il vostro codice originale funziona se si fa:

throw new Error "Dependent task '#{@parent.name}' is not completed." 

Se qualcosa si scrive in CoffeeScript sta producendo risultati che non hanno senso, provare a compilarlo js (o incollando il codice in try CoffeeScript Vedrai. che:

-> task2.complete().should.throw "Dependent task 'wash dishes' is not completed." 

compila a:

(function() { 
    return task2.complete().should["throw"]("Dependent task 'wash dishes' is not completed."); 
}); 

che definisce semplicemente una funzione e non lo esegue Questo spiega perché cambiare la corda non fa differenza. Spero che aiuti.

+0

la mia opinione: aggiungere parentesi per avvolgere il corpo della funzione, renderebbe l'esempio coffeescript più chiaro: (-> task2.complete()). Should.throw "Il compito dipendente" lavare i piatti "non è completo." –

3

Prima di tutto, questo è un po 'bello CoffeeScript.

Secondo, David Weldon ha ragione nella sua risposta che si può semplicemente cambiare il tiro per lanciare effettivamente un errore e funziona.

Ecco il codice messo in un unico file lungo con solo il tiro cambiato.

class TaskList 

class Task 
    constructor: (@name) -> 
     @status = 'incomplete' 
    complete: -> 
     if @parent? and @parent.status isnt 'completed' 
      throw new Error "Dependent task '#{@parent.name}' is not completed." 
     @status = 'complete' 
     true 
    dependsOn: (@parent) -> 
     @parent.child = @ 
     @status = 'dependent' 

# Prepare scope stuff 
root = exports ? window 
root.TaskList = TaskList 
root.Task = Task 

should = require 'should' 

describe 'Task Instance', -> 
    task1 = task2 = null 
    it 'should have a name', -> 
     something = 'asdf' 
     something.should.equal 'asdf' 
     task1 = new Task 'feed the cat' 
     task1.name.should.equal 'feed the cat' 
    it 'should be initially incomplete', -> 
     task1.status.should.equal 'incomplete' 
    it 'should be able to be completed', -> 
     task1.complete().should.be.true 
     task1.status.should.equal 'complete' 
    it 'should be able to be dependent on another task', -> 
     task1 = new Task 'wash dishes' 
     task2 = new Task 'dry dishes' 
     task2.dependsOn task1 
     task2.status.should.equal 'dependent' 
     task2.parent.should.equal task1 
     task1.child.should.equal task2 
    it 'should refuse completion it is dependent on an uncompleted task', -> 
     (-> task2.complete()).should.throw "Dependent task 'wash dishes' is not completed." 

Mocha quel bastardo e sei a posto.