你如何检查一个函数 returns 是否是 Jasmine 中的一个对象?

How do you check if a function returns an object in Jasmine?

示例:

expect(bst.find(5)).toBe(<an object>);

我如何确定它是具有以下三个属性的对象:valleftright

编辑:

这有效 - http://jsfiddle.net/1d9h2L2z/1/

但这不是:

describe('A Binary Search Tree', function() {
  var bst;
  beforeEach(function() {
    this.addMatchers({
      toBeANode: function () {
        return this.actual.val !== undefined && this.actual.left !== undefined && this.actual.right !== undefined;
      }
    });
    bst = new BST();
    bst.insert(4);
    bst.insert(2);
    bst.insert(1);
    bst.insert(3);
    bst.insert(6);
    bst.insert(5);
    bst.insert(7);
    //       4
    //   2       6
    // 1   3   5   7
  });
  it('can do preorder traversal', function() {
    expect(bst.preorder()).toBe('4213657');
  });
  it('can do inorder traversal', function() {
    expect(bst.inorder()).toBe('1234567');
  });
  it('can do postorder traversal', function() {
    expect(bst.postorder()).toBe('1325764');
  });
  it('can do levelorder traversal', function() {
    expect(bst.levelorder()).toBe('4261357');
  });
  it('can get the minimum', function() {
    expect(bst.min()).toBeANode();
    expect(bst.min().val).toBe(1);
  });
  it('can get the maximum', function() {
    expect(bst.max()).toBeANode();
    expect(bst.max().val).toBe(7);
  });
  it('can find', function() {
    expect(bst.find(5)).toBeANode();
    expect(bst.find(5).val).toBe(5);
    expect(bst.find(10)).toBe(-1);
  });
  it('can findParent', function() {
    expect(bst.findParent(5)).toBeANode();
    expect(bst.findParent(5).val).toBe(6);
    expect(bst.findParent(8)).toBe(-1); // nonexistant node
    expect(bst.findParent(4)).toBe(-1); // root
  });
  it('can remove a leaf node', function() {
    bst.remove(7);
    expect(bst.inorder()).toBe('123456');
  });
  it('can remove a node with one child', function() {
    bst.insert(8);
    bst.remove(7);
    expect(bst.inorder()).toBe('1234568');
  });
  it('can remove a node with two children', function() {
    bst.insert(2.1);
    bst.remove(2);
    expect(bst.inorder()).toBe('12.134567'); // right subtree has a left subtree
    bst.insert(8);
    bst.remove(6);
    expect(bst.inorder()).toBe('12.134578'); // right subtree doesn't have a left subtree
  });
  // add AVL stuff
});

英国夏令时:

function BSTNode(val) {
    this.val = val;
    this.left = null;
    this.right = null;
}
function BST() {
    this.root = null;
}
BST.prototype._isEmpty = function() {
    return this.root === null;
};
BST.prototype.insert = function(el, root) {
    var n = new BSTNode(el);
    if (this._isEmpty()) this.root = n;
    else {
        root = root || this.root;
        if (el < root.val) {
            if (!root.left) root.left = n;
            else this.insert(el, root.left);
        }
        else {
            if (!root.right) root.right = n;
            else this.insert(el, root.right);
        }
    }
};
BST.prototype.preorder = function() {
    var retStr = '';
    function innerPreorder(curr) {
        if (curr === null) return;
        else {
            retStr += curr.val;
            innerPreorder(curr.left);
            innerPreorder(curr.right);
        }
    }
    innerPreorder(this.root);
    return retStr;
};
BST.prototype.inorder = function() {
    var retStr = '';
    function innerInorder(curr) {
        if (curr === null) return;
        else {
            innerInorder(curr.left);
            retStr += curr.val;
            innerInorder(curr.right);
        }
    }
    innerInorder(this.root);
    return retStr;
};
BST.prototype.postorder = function() {
    var retStr = '';
    function innerPostorder(curr) {
        if (curr === null) return;
        else {
            innerPostorder(curr.left);
            innerPostorder(curr.right);
            retStr += curr.val;
        }
    }
    innerPostorder(this.root);
    return retStr;
};
BST.prototype.levelorder = function() {
    var retStr = '';
    var queue = [];
    queue.push(this.root);
    var curr;
    while (queue.length > 0) {
        curr = queue.shift();
        retStr += curr.val;
        if (curr.left) queue.push(curr.left);
        if (curr.right) queue.push(curr.right);
    }
    return retStr;
};
BST.prototype.min = function(curr) {
    curr = curr || this.root;
    while (curr.left) {
        curr = curr.left;
    }
    return curr;
};
BST.prototype.max = function(curr) {
    curr = curr || this.root;
    while (curr.right) {
        curr = curr.right;
    }
    return curr;
};
BST.prototype.find = function(val) {
    var curr = this.root;
    while (curr) {
        if (val === curr.val) return curr;
        else if (val < curr.val) curr = curr.left;
        else if (val > curr.val) curr = curr.right;
    }
    return -1;
};
BST.prototype.findParent = function(val) {
    if (this.root.val === val) return false;
    function innerFindParent(val, curr) {
        if (!curr.left && !curr.right) return false;
        if (curr.left.val === val) return curr;
        else if (curr.right.val === val) return curr;
        else {
            var retVal;
            if (curr.left) {
                retVal = this.findParent(val, curr.left);
                if (retVal) return retVal;
            }
            if (curr.right) {
                retVal = this.findParent(val, curr.right);
                if (retVal) return retVal;
            }
            return false;
        }
    }
    return innerFindParent(val, this.root);
};

你可以写一个'custom matcher'。这个想法是您创建自己的匹配器函数,该函数可以比较特定值并且比标准 isEqual 匹配器更具体。 您可以在这里阅读更多内容:http://jasmine.github.io/2.0/custom_matcher.html

这是针对您的具体情况的 fiddle: http://jsfiddle.net/1d9h2L2z/

//in your beforeEach you define your custom matcher:    
beforeEach(function () {
            this.addMatchers({
                // val, left, and right
                toBeAValidObjectPerDef: function () {
                    return (this.actual.val !== jasmine.undefined && this.actual.left !== jasmine.undefined && this.actual.right != jasmine.undefined);
                }
            })
        });


    describe('MyObject', function () {

        it('is a valid object with val, left and right', function () {
            // and here is how you can call it - instead of testObject you can use the one returned by your function
            var testObject = new TestObject('foo', 'leftValue', 'rightValue');
            expect(testObject).toBeAValidObjectPerDef();

        });
    });