我试图用sinon测试快速路由器的功能。我的测试如下,第一次测试通过就没问题了。然而第二个没有通过。我无法弄清楚原因。
如果我向路线发送http请求,它会按预期工作。
关于渔获物的一些事情正在引发问题。下面是我能够将其简化为错误的代码
books.js
import express from 'express';
import models from '../db/models';
const router = express.Router();
var indexPost = async (req, res, next) => {
try {
let savedBook = await models.Book.create({
title: req.body.title || null,
isbn: req.body.isbn || null,
author: req.body.author || null
});
res.status(201).json({ book: savedBook.id });
} catch (err) {
res.status(400).send('');
}
};
router.post('/', indexPost);
export default router;
export { indexPost };
books.test.js
import { indexPost } from '../../../src/routes/books';
import models from '../../../src/db/models';
import sinon from 'sinon';
import { expect } from 'chai';
import sinonTestFactory from 'sinon-test';
const sinonTest = sinonTestFactory(sinon);
describe('Books router', () => {
describe('indexPost', () => {
it('should save the book to the database', sinonTest(async function () {
let req = {
body: {
title: 'Book Title',
isbn: '123asera23',
author: 123
}
};
let res = {
status: status => {},
json: json => {}
};
this.stub(res, 'status').returns(res);
this.stub(res, 'json').returns(res);
indexPost(req, res);
let book = await models.Key.findById(1);
expect(book.title).to.equal('Book Title');
expect(book.isbn).to.equal('123asera23');
expect(book.author).to.equal(123);
sinon.assert.calledWith(res.status, 201);
sinon.assert.calledWith(res.json, { book: 1 });
}));
it('should throw an error if data is not all there', sinonTest(async function () {
let req = {
body: {
title: 'Book Title',
author: 123
}
};
let res = {
status: status => {},
send: send => {}
};
this.stub(res, 'status').returns(res);
this.stub(res, 'send').returns(res);
indexPost(req, res);
sinon.assert.calledWith(res.status, 400);
sinon.assert.calledWith(res.send, '');
}));
});
});
错误
1) Books router
indexPost
should throw an error if data is not all there:
AssertError: expected status to be called with arguments
at Object.fail (/var/app/node_modules/sinon/lib/sinon/assert.js:96:21)
at failAssertion (/var/app/node_modules/sinon/lib/sinon/assert.js:55:16)
at Object.assert.(anonymous function) [as calledWith] (/var/app/node_modules/sinon/lib/sinon/assert.js:80:13)
at Context.<anonymous> (tests/src/routes/books.test.js:58:20)
at Generator.next (<anonymous>)
at step (tests/src/routes/books.test.js:21:191)
at tests/src/routes/keys.test.js:21:437
at new Promise (<anonymous>)
at Context.<anonymous> (tests/src/routes/books.test.js:21:99)
at callSandboxedFn (/var/app/node_modules/sinon-test/lib/test.js:94:25)
at Context.sinonSandboxedTest (/var/app/node_modules/sinon-test/lib/test.js:114:24)
答案 0 :(得分:0)
由于没有人看到这一点意识到这不是一个不平等的断言,我会发布我最终想出的真正答案。
基本上我接近测试错了。我只考虑了javascript中的非异步代码。
我需要做的是返回对mocha的it
函数的承诺。为了做到这一点,我的控制器也需要返回一个承诺。在做数据库工作的情况下,我可以返回数据库调用promise。
承诺调用resolve
或reject
后。然后,您可以执行断言以查看测试是否有效。
关键是你必须将你的承诺从你的控制器底部链接到mocha的it
函数。
以下是解决此问题的代码。
import express from 'express';
import models from '../db/models';
const router = express.Router();
var indexPost = (req, res, next) => {
return models.Book.create({
title: req.body.title || null,
isbn: req.body.isbn || null,
author: req.body.author || null
}).then(savedBook => {
res.status(201).json({ book: savedBook.id });
}).catch(err => {
res.status(400).send('');
});
};
router.post('/', indexPost);
export default router;
export { indexPost };
import { indexPost } from '../../../src/routes/books';
import models from '../../../src/db/models';
import sinon from 'sinon';
import { expect } from 'chai';
describe('Books router', () => {
describe('indexPost', () => {
it('should save the book to the database', async () => {
let req = {
body: {
title: 'Book Title',
isbn: '123asera23',
author: 123
}
};
const jsonStub = sinon.stub()
const res = { status: status => ({ json: jsonStub, send: err => err }) }
const statusSpy = sinon.spy(res, 'status')
return indexPost(req, res).then(() => {
let book = await models.Key.findById(1);
expect(book.title).to.equal('Book Title');
expect(book.isbn).to.equal('123asera23');
expect(book.author).to.equal(123);
sinon.assert.calledWith(res.status, 201);
sinon.assert.calledWith(res.json, { book: 1 });
})
}));
it('should throw an error if data is not all there', () => {
let req = {
body: {
title: 'Book Title',
author: 123
}
};
const sendStub = sinon.stub()
const res = { status: status => ({ json: err => err, send: sendStub }) }
const statusSpy = sinon.spy(res, 'status')
indexPost(req, res).then(() => {
sinon.assert.calledWith(res.status, 400);
sinon.assert.calledWith(res.send, '');
});
}));
});
});
我的响应对象中也有一些奇怪,上面的代码也解决了这个问题。