使用 sinon 和 chai 测试功能时出现问题
Issue when testing function with sinon and chai
我正在尝试开始对我的项目进行测试,有些事情我能够正确测试,但其他事情则不能。这是我要测试的功能。
exports.rateReview = async (req, res, next) => {
try {
const review = await Review.findById(req.body.id);
if (review) {
if (req.body.type === 'like') await review.like();
if (req.body.type === 'dislike') await review.dislike();
}
res.send('Ok');
} catch (err) {
console.log(err);
}
}
我要测试的是,是否根据 req.body.type 调用 like() 和 dislike() 函数。这是我的测试文件。
const sinon = require('sinon');
const chai = require('chai');
const sinonChai = require("sinon-chai");
const mongoose = require('mongoose');
const seriesController = require('../../../../src/series-search/controllers/series.controller');
const Review = require('../../../../src/series-search/models/Review');
const expect = chai.expect;
chai.use(sinonChai);
let spyFindById, spyLike, spyDislike;
beforeEach(() => {
spyLike = sinon.spy(Review.prototype, 'like');
spyDislike = sinon.spy(Review.prototype, 'dislike');
spyFindById = sinon.stub(Review, 'findById').returns({});
});
afterEach(() => {
spyLike.restore();
spyDislike.restore();
spyFindById.restore();
});
describe('Series controller', () => {
describe('search()', () => {
});
describe('addReview()', () => {
it('should call findById() with review id');
});
describe('rateReview()', () => {
it('should call review.like() if type is like', (done) => {
const req = {
body: {
id: '123456',
type: 'like'
}
};
const res = {
send: sinon.stub()
};
const spyLike = sinon.spy(review, 'like');
seriesController.rateReview(req, res, null);
expect(spyLike).to.have.been.calledOnce;
done();
});
it('should call review.dislike() if type is dislike');
});
});
测试一直失败,因为它说期望 'like' 被调用一次但它没有。我尝试了很多东西并在 Google 上搜索了很多,但我无法让它工作。如果有人有任何想法,我将不胜感激。
谢谢!
执行此操作的正确方法是 return like
和 dislike
当您存根 findById
方法时。
....
let spyFindById, spyLike, spyDislike;
beforeEach(() => {
spyLike = sinon.spy();
spyDislike = sinon.spy();
// spy `like` and `dislike` here so our `review` variable can be spied.
// use `resolves` since it is promised based function
spyFindById = sinon.stub(Review, 'findById').resolves({
like: spyLike,
dislike: spyDislike
});
});
afterEach(() => {
sinon.restore(); // use sinon.restore() is enough if you use the latest Sinon
});
describe('Series controller', () => {
describe('rateReview()', () => {
// no need to use `done` if we can use `async await`
it('should call review.like() if type is like', async () => {
const req = {
body: {
id: '123456',
type: 'like'
}
};
const res = {
send: sinon.stub()
};
await seriesController.rateReview(req, res, null);
expect(spyLike).to.have.been.calledOnce;
});
it('should call review.dislike() if type is dislike');
});
});
我正在尝试开始对我的项目进行测试,有些事情我能够正确测试,但其他事情则不能。这是我要测试的功能。
exports.rateReview = async (req, res, next) => {
try {
const review = await Review.findById(req.body.id);
if (review) {
if (req.body.type === 'like') await review.like();
if (req.body.type === 'dislike') await review.dislike();
}
res.send('Ok');
} catch (err) {
console.log(err);
}
}
我要测试的是,是否根据 req.body.type 调用 like() 和 dislike() 函数。这是我的测试文件。
const sinon = require('sinon');
const chai = require('chai');
const sinonChai = require("sinon-chai");
const mongoose = require('mongoose');
const seriesController = require('../../../../src/series-search/controllers/series.controller');
const Review = require('../../../../src/series-search/models/Review');
const expect = chai.expect;
chai.use(sinonChai);
let spyFindById, spyLike, spyDislike;
beforeEach(() => {
spyLike = sinon.spy(Review.prototype, 'like');
spyDislike = sinon.spy(Review.prototype, 'dislike');
spyFindById = sinon.stub(Review, 'findById').returns({});
});
afterEach(() => {
spyLike.restore();
spyDislike.restore();
spyFindById.restore();
});
describe('Series controller', () => {
describe('search()', () => {
});
describe('addReview()', () => {
it('should call findById() with review id');
});
describe('rateReview()', () => {
it('should call review.like() if type is like', (done) => {
const req = {
body: {
id: '123456',
type: 'like'
}
};
const res = {
send: sinon.stub()
};
const spyLike = sinon.spy(review, 'like');
seriesController.rateReview(req, res, null);
expect(spyLike).to.have.been.calledOnce;
done();
});
it('should call review.dislike() if type is dislike');
});
});
测试一直失败,因为它说期望 'like' 被调用一次但它没有。我尝试了很多东西并在 Google 上搜索了很多,但我无法让它工作。如果有人有任何想法,我将不胜感激。
谢谢!
执行此操作的正确方法是 return like
和 dislike
当您存根 findById
方法时。
....
let spyFindById, spyLike, spyDislike;
beforeEach(() => {
spyLike = sinon.spy();
spyDislike = sinon.spy();
// spy `like` and `dislike` here so our `review` variable can be spied.
// use `resolves` since it is promised based function
spyFindById = sinon.stub(Review, 'findById').resolves({
like: spyLike,
dislike: spyDislike
});
});
afterEach(() => {
sinon.restore(); // use sinon.restore() is enough if you use the latest Sinon
});
describe('Series controller', () => {
describe('rateReview()', () => {
// no need to use `done` if we can use `async await`
it('should call review.like() if type is like', async () => {
const req = {
body: {
id: '123456',
type: 'like'
}
};
const res = {
send: sinon.stub()
};
await seriesController.rateReview(req, res, null);
expect(spyLike).to.have.been.calledOnce;
});
it('should call review.dislike() if type is dislike');
});
});