1

我有这个按环境配置knex的功能

const knexConnection = () => {
   const config = require('./connection')[environment];
   return knex(config) 
}

我在我的 route.js 中使用了这个函数

module.exports = (app) => {
    app.get("/test", (req,res)=>{
            knexConnection().raw("SELECT NOW() as time").then(result => {
                const time = _.get(result.rows[0],'time')
                res.send(time);
            }).catch(err => throw(err))
        })

 }

我的 route.js 测试文件

const sinon = require("sinon");
const chai = require("chai");
const mock = require('proxyquire')
const httpStatus = require('http-status');
const expect = chai.expect;

    const myStub = sandbox.stub().resolves("Query executed")
     const route = mock('../routes', {'../../knexConntection':knexConnection : { raw: myStub }}})

        route(app)

        chai.request(app)
            .get('/test')
            .set('content-type', 'application/x-www-form-urlencoded')
            .end((err, res) => {
                if (err) done(err);
                expect(myStub).to.have.been.called;
                expect(res.status).to.equal(200)
                done();
            })

当我执行测试文件时,knexConnection.raw 被存根并显示当前时间。并且测试失败。它说存根从未被调用过。

我已经尝试了几天,它仍然没有工作。知道如何存根 knex 查询吗?

更新

在挣扎了几个小时之后,我认为存根被跳过了,因为应用程序在存根之前被实例化。所以存根永远不会被加载。

我的服务器结构有这个结构。

-- 服务器.js

//...all server stuff
//load all modeles routes using route
route(app)

这是我的 index.js,因为我在服务器应用程序中动态加载所有路由。

var fs = require("fs");

module.exports = app => {
  fs.readdirSync(__dirname).forEach(file => {
    if (file == "index.js") return;

    const name = file.substr(0, file.indexOf("."));
    require("./" + name)(app);
  });
};

我的模拟仍然被跳过,应用程序首先被调用。

4

1 回答 1

1

您不能将 raw 更改为knexConnection函数而不是对象。

knexConnection().raw(...).then(...)

也就是说,它是一个返回具有原始函数的对象的函数。

此外,我们还可以在处理 knexConnection 时存根。所以我们可以控制是什么raw

const promise = sinon.stub().resolves("Query executed")
const knexConnection = sinon.stub().returns({
   raw: promise
})

还有一件事,我用过摩卡。为了将存根从 beforeEach 传递给它,我使用this.currentTest(in beforeEach) 和this.test(in it)。见评论。

这使我的测试通过:

// Import the dependencies for testing
const chai = require('chai');
const chaiHttp = require('chai-http');
const app = require('../server');
const route = require('../route');

const sinon = require("sinon");
const mock = require('proxyquire')
const httpStatus = require('http-status');
const expect = chai.expect;

chai.use(chaiHttp);
chai.should();

describe("test routes", () => {

  beforeEach(function() {

    const promise = sinon.stub().resolves("Query executed")
    // runs before all tests in this block
    const knexConnection = sinon.stub().returns({
        raw: promise
    })

    this.currentTest.myStub = promise //so as to access this in 'it' with this.test.myStub

    // warning : {'./knex': { knexConnection : knexConnection }} would replace knexConnection in route file
// with an object { knexConnection : knexConnection } causing the test to fail.
// Instead, you should write {'./knex': knexConnection}
    const route = mock('../route', {'./knex': knexConnection})

    route(app)
  });

  it("should call myStub", function(done) {
      var myStub = this.test.myStub;
        chai.request(app)
        .get('/test')
        .set('content-type', 'application/x-www-form-urlencoded')
        .end((err, res) => {
            if (err) done(err);
            sinon.assert.called(myStub);
            done();
        })
  })

  it("should have 'Query executed' as text", function(done) {
      var myStub = this.test.myStub;
        chai.request(app)
        .get('/test')
        .set('content-type', 'application/x-www-form-urlencoded')
        .end((err, res) => {
            if (err) done(err);
            sinon.assert.match(res.text, "Query executed")
            done();
        })
  })

    it("should have 200 as status", (done) => {
        chai.request(app)
        .get('/test')
        .set('content-type', 'application/x-www-form-urlencoded')
        .end((err, res) => {
            if (err) done(err);
            expect(res.status).to.equal(200)
            done();
        })
  })  
})

路线文件:

const knexConnection = require('./knex.js');

module.exports = (app) => {
    app.get("/test", (req,res)=>{
            knexConnection().raw("SELECT NOW() as time").then(result => {
                res.send(result);
            }).catch(err => { throw(err) })
        })

 }

如果您还有其他问题,请尽管提问。

于 2019-10-02T03:14:55.243 回答