我如何使用sinon来存储neo4j Thingdom模块的函数

时间:2013-05-23 14:35:53

标签: javascript node.js sinon

我在编写一些单元测试时遇到了一些问题,我希望将neo4j Thingdom模块的功能存根。

经过几个小时的尝试失败后,我一直在网上搜索,我找到的唯一参考点是一个用于sinon.createStubInstance的示例项目(neo4j.GraphDatabase);去除整个对象。对我来说,因为这似乎是一个扔掉项目,我想要一个更细粒度的方法,所以我可以测试,例如,当保存你创建它的节点(非持久化)时,Thingdom API概述坚持它然后你可以索引它,如果你希望哪个是三个调用,并且可以在多个特定测试中概述,我不确定可以通过createStubInstance设置实现(即如果函数被调用一次就找到)。

示例“创建节点”函数(这只是为了说明函数,我试图使用测试来构建它)

User.create = function(data, next){
    var node = db.createNode(data);

    node.save(function(err, node){
        next(null,node);
    });
};

我能够存储顶级对象(neo4j.GraphDatabase)的函数,所以这可行:

    it('should create a node for persistence', function(){
        var stub = sinon.stub(neo4j.GraphDatabase.prototype, 'createNode');

        User.create({}, res);

        stub.calledOnce.should.be.ok;
        stub.restore();
    });   

问题是我想运行的下一组测试,如果调用持久化节点到数据库的调用(节点,保存)方法:

我不确定这是否可行或者是否可以实现但是我已经尝试了存根的几种变体而且似乎无效(在neo4j.Node,neo4j.Node.prototype上)并且它们都会带来不同的错误例如无法包装undefined等,这可能是由于createNode函数直接生成节点而不是我的代码。

有什么我明显做错了,我错过了诀窍还是你不能这样做?如果不是处理这类事情的最佳策略是什么?

2 个答案:

答案 0 :(得分:1)

一种可能的解决方案是返回一个存根或模拟对象,让您控制创建节点后会发生什么:

it('should create a node for persistence and call save', function () {
    var stubbedNode = {
        save: sinon.stub().yields(undefined, stubbedNode)
    };

    var stub = sinon.stub(neo4j.GraphDatabase.prototype, 'createNode').returns(stubbedNode);

    User.create({}, res);

    stub.calledOnce.should.be.ok;
    stub.restore();
    stubbedNode.save.calledOnce.should.be.ok;
});

答案 1 :(得分:0)

我们无法直接进行,模块的设置方式与Sinon无法正常工作。我们正在做的只是将模块抽象出来并将其包装在一个简单的外观/适配器中,我们可以在单元测试中存根。

由于我们没有做任何事情调用该类中的neo4j模块,我们正在集成(并将在回归测试时验证)测试该部分以确保我们正在访问neo4j数据库。