Nodeunit test.throws, похоже, не улавливает ошибку - PullRequest
9 голосов
/ 11 августа 2011

Я пытаюсь создать набор тестов для модуля, который пишу в Node.js, используя Nodeunit. Модуль представляет собой базовый музыкальный плейлист, который позволяет добавлять и удалять треки в плейлист.

var playlist = function(){
    this.__playlist = [];
    this.__count = 0;
};

playlist.prototype = {
    addtrack:function(track){
        if(typeof track !== "object") throw new Error("Track needs to be an oject");
        this.__count++;
        track.id = this.__count;
        this.__playlist.push(track);
        return this.__playlist;
    },
    removetrack:function(trackid){
        if(typeof trackid !== "number") throw new Error("Pass in a numeric track id");
        var trackFound = false;
        for(var i=0;i<this.__playlist.length;i++){
            var t = this.__playlist[i];
            if(t.id == trackid){
                trackFound = true;
                this.__playlist.splice(i,1);
            }
        }
        if(!trackFound) throw new Error("Track not found in the playlist");
        return this.__playlist
    }
}

exports.playlist = function(){
    return new playlist();
}

Как вы можете видеть, есть места, которые выдают ошибки из-за неверной передачи данных.

Итак, вот мой набор тестов.

var pl = require('./playlist');

exports.testPlaylistInit = function(test){
    var playlist = pl.playlist();
    test.equal(typeof playlist, 'object');
    test.done();
}

exports.testAddingTracks = function(test){
    var playlist = pl.playlist();
    test.throws(playlist.addtrack(), Error, 'Should fail for blank track');
    var track = {
        title: "Golly Sandra",
        artist: "Eisley",
        album: "Room Noises"
    };
    tracks = playlist.addtrack(track);
    test.equals(tracks[0],track);
    test.equals(tracks[0].id,1)
    test.done();
}

exports.testRemoveingTracks = function(test){
    var playlist = pl.playlist();
    test.throws(playlist.removetrack('Imma error'), Error, 'Show fail for non-numeric track id');
    var track = {
        title: "Golly Sandra",
        artist: "Eisley",
        album: "Room Noises"
    };
    playlist.addtrack(track);
    track = {
        title: ".44 Calliber Love Letter",
        artist: "Alexisonfire",
        album: "Alexisonfire"
    }
    playlist.addtrack(track);
    test.equals(playlist.removetrack(1)[0],track);
    test.throws(playlist.removetrack(10), Error, 'Should fail for non-existant track');
    test.done();
}

При написании набора тестов я использовал test.throws, так как предположение в основном просто заключает блок кода в оператор try-catch и проверяет перехват против блока ошибки. Очевидно, я ошибаюсь, потому что, когда я запускаю тест с Nodeunit, Node отображает сообщение об ошибке, выданное модулем вместо набора тестов, улавливающего ошибку. Я неправильно использую файл test.throw?

1 Ответ

23 голосов
/ 11 августа 2011

Ваше использование test.throws не совсем верно.Если вы посмотрите на то, что у вас есть:

test.throws(
  playlist.removetrack('Imma error'),
  Error,
  'Show fail for non-numeric track id'
);

Вы выполняете playlist.removetrack('Imma error'), а затем передаете результат этого броскам, поэтому, если есть исключение, это произойдет до того, как броски будут выполнены.

Вы должны сделать что-то более похожее на это:

test.throws(
  function() {
    playlist.removetrack('Imma error');
  }, 
  Error,
  'Show fail for non-numeric track id'
);

Вы должны передать функцию, которая при выполнении попытается удалить дорожку.Таким образом, ваша логика списка воспроизведения фактически выполняется функцией throws и, таким образом, может автоматически переноситься в блок try / catch.

...