[英]How can I test my asynchronous code in a restify HTTP handler?
我在Restify項目中有一個處理HTTP GET請求的函數。 經過一些處理后,它使用Sequelize查找當前會話的用戶實體。 User.findOne
函數返回一個promise,並根據該promise的結果,我發送一個200或404的HTTP響應。
static getMe(req, res, next) {
const userInfo = BaseController.getUserSession(req);
// hard to test this part
User.findOne({
where: {email: userInfo.email}
}).then(function(user) {
if (user) BaseController.respondWith200(res, user);
else BaseController.respondWith404(res, 'User not found.');
}, function(error) {
BaseController.respondWith404(res, error);
}).then(function() {
return next();
});
}
我已經嘗試了幾個不同的庫來幫助測試,所以如果這是一個混亂的事情,我很抱歉。 這是我的beforeEach
函數,用於我的測試:
const usersFixture = [
{id:2, email:'ozzy@osbourne.com', facebookId:54321, displayName: 'Ozzy Osbourne'},
{id:3, email:'zakk@wylde.com', facebookId:34521, displayName: 'Zakk Wylde'},
{id:4, email:'john@lennon.com', facebookId:12453, displayName: 'John Lennon'}
];
this.findOneSpy = sinon.spy(function(queryObj) {
return new Promise(function(resolve, reject) {
const user = usersFixture.find(function(el) { return el.email === queryObj.where.email });
if (user) resolve(user);
else resolve(null);
});
});
this.respondWith200Spy = sinon.spy(function(res, data) {});
this.respondWith400Spy = sinon.spy(function(res, error) {});
this.respondWith404Spy = sinon.spy(function(res, error) {});
this.controller = proxyquire('../../controllers/user-controller', {
'../models/user': {
findOne: this.findOneSpy
},
'./base-controller': {
respondWith200: this.respondWith200Spy,
respondWith400: this.respondWith400Spy,
respondWith404: this.respondWith404Spy
}
});
這是我的一個測試看起來像:
it('should return 200 with user data if user email matches existing user', function() {
// THIS FUNCTION IS NEVER HIT
this.respondWith200Spy = function(res, data) {
data.should.equal({id:4, email:'john@lennon.com', facebookId:12453, displayName: 'John Lennon'});
done();
};
const req = {session:{user:{email:'john@lennon.com'}}};
this.controller.getMe(req, this.res, this.nextSpy);
this.findOneSpy.should.have.been.called;
});
因為我們實際上沒有將回調傳遞給函數,並且函數沒有真正返回任何東西(只是在其他地方做異步事情),我無法弄清楚如何測試它以確保它正常工作。 任何幫助表示贊賞。
實際代碼工作得很好。 我只是想在項目中進行一些高質量的單元測試。 謝謝!
我最終找到了使用proxyquire做到這一點的方法。 我剛剛重新respondWith200
了我正在測試的控制器類,並使respondWith200
回調作出斷言。 然后我為next
調用done
函數創建了一個新的間諜(傳遞給測試用例)。 我驗證了代碼都被點擊了。
it('should return 200 with user data if user email matches existing user', function(done) {
const controller = proxyquire('../../controllers/user-controller', {
'../models/user': {
findOne: this.findOneSpy
},
'./base-controller': {
respondWith200: function(res, data) {
data.displayName.should.equal('John Lennon');
},
respondWith400: this.respondWith400Spy,
respondWith404: this.respondWith404Spy
}
});
const req = {grft_session:{user:{email:'john@lennon.com'}}};
const nextSpy = sinon.spy(function() {
done();
});
controller.getMe(req, this.res, nextSpy);
this.findOneSpy.should.have.been.called;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.