0

このクラスの使用:

var Observer = function Observer() {
    this._events = {};
};

Observer.prototype.on = function(k, v) {
    (this._events[k] = this._events[k] || []).push(v);
};

Observer.prototype.off = function(k, v) {
    var hs;
    var i;
    var l;

    if (!k) {
        this._events = {};
        return;
    }

    if (!v) {
        if (typeof this._events[k] !== 'undefined') {
            this._events[k] = [];
        }
        return;
    }

    hs = this._events[k];
    i = 0;
    l = hs.length;
    while(i < l) {
        if (hs[i] === v) {
            hs.splice(i);
        }
        i++;
    }
};

Observer.prototype.emit = function(k) {
    var hs = this._events[k];
    var args;
    var i;
    var l;

    if (hs) {
        args = [].splice.call(arguments, 1);
        i = 0;
        l = hs.length;

        while(i < l) {
            hs[i].apply(this, args);
            i++;
        }
    }
};

if (typeof exports !== 'undefined') {
    exports.Observer = Observer;
}

そしてこのテストコード:

var assert = require('assert');
var Observer = require('../../public/lib/Observer').Observer;

describe('Observer', function() {
    beforeEach(function(done) {
        this.instance = new Observer();
        done();
    });

    describe('#on', function() {
        describe('with an event and handler', function() {
            it('should call a callback', function(done) {
                var expected = 0;

                this.instance.on('a', function(actual) {
                    assert.equal(expected, actual);
                    done();
                });

                this.instance.emit('a', expected);
            });
        });
    });

    describe('#off', function() {
        describe('with an event and a handler', function() {
            it('should not call the callback', function(done) {
                var expected = false;
                var actual = false;

                var f = function() {
                    actual = true;
                };

                this.instance.on('a', f);

                this.instance.off('a', f);

                this.instance.emit('a');

                assert.equal(expected, actual);

                done()
            });
        });

        describe('with an event', function() {
            it('should not call the callback', function(done) {
                var expected = false;
                var actual = false;

                var f = function() {
                    actual = true;
                };

                this.instance.on('a', f);

                this.instance.off('a');

                this.instance.emit('a');

                assert.equal(expected, actual);

                done()
            });
        });

        describe('without arguments', function() {
            it('should not call the callback', function(done) {
                var expected = false;
                var actual = false;

                var f = function() {
                    actual = true;
                };

                this.instance.on('a', f);

                this.instance.off('a');

                this.instance.emit('a');

                assert.equal(expected, actual);

                done()
            });
        });
    });

    describe('#emit', function() {
        describe('with an event and variable arguments', function() {
            // I've already used this method in the other tests, so it must work in
            // order for them to pass. But that's not isolated testing, help :(..
        });
    });
});

これらのテストを (mocha を使用して) 実行すると、それらすべてに合格しますが、一緒にテストされます。

  1. これは、1 つのフローに含まれるすべてのメソッドを使用して、このコードをテストする正しい方法ですか?

  2. これらのメソッドを個別にテストするにはどうすればよいですか?

    2.1. インターフェイスではなく実装をテストするだけなので、テストしている構造の内部を見ることはできません。

    2.2. .on(ev, fn)では、成功するための基準は何でしょうか?

4

1 に答える 1

0

その前に「on」を呼び出さない場合、off 関数は期待どおりに動作しますか? テスト フレームワークがサポートしている場合は、モックを使用することもできます。

于 2013-04-28T00:39:48.287 に答える