首页 文章

诗乃 Spy 没有触发

提问于
浏览
0

我无法追查为什么没有触发一个罪人 Spy . 在下面的测试中,两个控制台语句都报告为false,因此没有调用任何方法(如果有错误) .

这是我的一个mocha测试通常看起来像:

describe('Post Controller', function () {
    var controller = require('../controllers/PostController'),
    req = {
        user: {
            check_id: "00100",
            access_id: "54876329"
        }
    };

beforeEach(function () {
    res = {
        send: sinon.spy(),
        json: sinon.spy()
    };
});

afterEach(function () {
    res.send.reset();

});

describe('readAllPosts', function () {
    it('should return an array of posts', function (done) {
        controller.readAllPosts(req, res);
        process.nextTick(function () {
            console.log('send: ', res.send.called);
            console.log('json: ', res.json.called);
            assert(res.json.calledWith(sinon.match.array));
            done();
        });
    });
});

});

PostContoller中的 readAllPosts 方法:

var postController = {
    readAllPosts: function (req, res) {
        PostModel.find(
            {
                access_id: req.user.access_id
            },
            function (err, results) {
                if (err) {
                    res.send(404, err);
                } else {
                    // res here is a spy
                    res.json(results);
                }
            }
        );
    }
};

最后是PostModel中的 find 方法:

Posts.find= function (conditions, cb) {
    /* ... */
    dbQuery(query, function (err, results) {
        if (err) {
            cb(err);
        }

        cb(null, results);
    });
};

如果我以正常方式调用方法,则执行find,返回预期的Posts数组 . 但是 res Spy 永远不会被执行 . 此外,如果我将控制器类中的方法更改为此

var postController = {
    readAllPosts: function (req, res) {
        res.json([{this:"that",and:"other"}]);
    }
};

Spy 功能(res)起火 . 我知道发送给模型的回调正在被调用,并且res对象在那里,但它认为这是一个间接问题(调用原始方法而不是sinon包装的)但我不确定问题出在哪里所在 .

1 回答

  • 0

    使用Sinon Spy /存根测试异步函数很困难,因为(AFAIK)你无法告诉你它何时被调用(它甚至可能永远不会被调用) .

    在你的情况下,你假设 PostModel.find() 将在下一个勾号中完成(通过使用 process.nextTick() 判断),当查询仍然在运行时,很可能不会检查你的 Spy ,并且还没有调用任何 Spy .

    在我看来,你试图用一个测试来测试太多: PostModel.find()dbQuery()controller.readAllPosts() . 我可能会将它们分成不同的测试,然后将其余的测试分开 .

    因此,例如,如果要检查控制器是否发回正确的响应,或者它是否正确处理错误,则使用 PostModel.find() 让它与错误或正确的结果数组一起调用(同步)回调,然后检查 res.send/res.json Spy .

    另一种选择是不使用 Spy ,而是使用简单的回调 . 例如:

    controller.readAllPosts(req, {
      send : function(data) {
        assert(data, ...);
        done();
      },
      json : function(data) {
        assert(data, ...);
        done();
      },
    });
    

    (或其变体)

    但是,我不想这样做,因为它会阻止您(以一种简单的方式)测试,例如,不是这两种方法都被调用 .

相关问题