回答
您應該使用superagent。它是較低級別的模塊,由supertest
使用。看看部分Persisting an agent:
var request = require('superagent');
var user1 = request.agent();
user1
.post('http://localhost:4000/signin')
.send({ user: '[email protected]', password: 'password' })
.end(function(err, res) {
// user1 will manage its own cookies
// res.redirects contains an Array of redirects
});
現在你可以使用user1
進行認證的請求。
試試這個,
var request=require('supertest');
var cookie;
request(app)
.post('/login')
.send({ email: "[email protected]", password:'password' })
.end(function(err,res){
res.should.have.status(200);
cookie = res.headers['set-cookie'];
done();
});
//
// and use the cookie on the next request
request(app)
.get('/v1/your/path')
.set('cookie', cookie)
.end(function(err,res){
res.should.have.status(200);
done();
});
我會假設你正在使用的CookieSession中間件。
正如grub提到的,您的目標是獲得一個cookie值傳遞給您的請求。然而,無論出於何種原因(至少在我的測試中),supertest不會在同一測試中觸發2個請求。所以,我們必須反向工程師如何獲得正確的cookie值。首先,您需要使用模塊來構建您的Cookie:
var Cookie = require("express/node_modules/connect/lib/middleware/session/cookie")
, cookieSignature = require("express/node_modules/cookie-signature")
是的,這很醜陋。我把這些放在測試文件的頂部。
接下來,我們需要構建的cookie的值。我把這個變成一個beforeEach
對於需要身份驗證的用戶測試:
var cookie = new Cookie()
, session = {
passport: {
user: Test.user.id
}
}
var val = "j:" + JSON.stringify(session)
val = 's:' + cookieSignature.sign(val, App.config.cookieSecret)
Test.cookie = cookie.serialize("session",val)
Test.user.id
在定義我要「登錄」的用戶我beforeEach
鏈的一部分是以前定義。 session
的結構是Passport(至少當前)如何將當前用戶信息插入到會話中。
var val
行"j:"
和"s:"
從Connect CookieSession中間件中剝離出來,如果您使用的是基於Cookie的會話,Passport將回退。最後,我們序列化cookie。我把"session"
放在那裏,因爲這就是我配置cookie會話中間件的方式。此外,App.config.cookieSecret
在別處定義,它必須是您傳遞給Express/Connect CookieSession中間件的祕密。我把它存儲到Test.cookie
,以便我可以稍後訪問它。
現在,在實際測試中,你需要使用的cookie。例如,我有以下測試:
it("should logout a user", function(done) {
r = request(App.app)
.del(App.Test.versionedPath("/logout"))
.set("cookie", Test.cookie)
// ... other sets and expectations and your .end
}
通知調用set
與"cookie"
和Test.cookie
。這會導致請求使用我們構造的cookie。
現在你已經僞裝你的應用程序,認爲用戶已登錄,並且你不必保持實際的服務器運行。
或者,您可以直接測試您的請求處理程序,並將其傳遞給一些虛擬請求和res對象。當然,這不會測試你的路由。 – juanpaco
正如zeMirco指出的,底層superagent
模塊支持會話,爲您自動維護cookie。但是,可以從supertest
使用superagent.agent()
功能,通過一個未公開的特性。
只需使用require('supertest').agent('url')
代替require('supertest')('url')
:
var request = require('supertest');
var server = request.agent('http://localhost:3000');
describe('GET /api/getDir', function(){
it('login', loginUser());
it('uri that requires user to be logged in', function(done){
server
.get('/api/getDir')
.expect(200)
.end(function(err, res){
if (err) return done(err);
console.log(res.body);
done()
});
});
});
function loginUser() {
return function(done) {
server
.post('/login')
.send({ username: 'admin', password: 'admin' })
.expect(302)
.expect('Location', '/')
.end(onResponse);
function onResponse(err, res) {
if (err) return done(err);
return done();
}
};
};
如果你把你的app.js放入'''request.agent(app);'''它可以在沒有運行服務器的情況下工作。很酷的東西。 – shredding
現在這個解決方案的工作。 –
作爲附錄安迪的回答,纔能有Supertest啓動你的服務器,你可以做到這一點是這樣的:
var request = require('supertest');
/**
* `../server` should point to your main server bootstrap file,
* which has your express app exported. For example:
*
* var app = express();
* module.exports = app;
*/
var server = require('../server');
// Using request.agent() is the key
var agent = request.agent(server);
describe('Sessions', function() {
it('Should create a session', function(done) {
agent.post('/api/session')
.send({ username: 'user', password: 'pass' })
.end(function(err, res) {
expect(req.status).to.equal(201);
done();
});
});
it('Should return the current session', function(done) {
agent.get('/api/session').end(function(err, res) {
expect(req.status).to.equal(200);
done();
});
});
});
應該是'expect(res.status)'而不是'req.status'。 – 2015-12-09 21:50:17
對不起,但建議的解決方案都不適合我。
隨着supertest.agent()
我不能使用app
情況下,我需要事先運行服務器,並指定http://127.0.0.1:port
,而且我不能使用supertest的預期(斷言),我不能使用supertest-as-promised
lib和等等...
cookies
的情況根本不適用於我。
所以,我的解決辦法是:
如果您正在使用Passport.js,它利用了「承載令牌」機制,您可以在您的規格使用下面的例子:
var request = require('supertest');
var should = require('should');
var app = require('../server/app.js'); // your server.js file
describe('Some auth-required API', function() {
var token;
before(function (done) {
request(app)
.post('/auth/local')
.send({
email: '[email protected]',
password: 'the secret'
})
.end(function (err, res) {
if (err) {
return done(err);
}
res.body.should.to.have.property('token');
token = res.body.token;
done();
});
});
it('should respond with status code 200 and so on...', function (done) {
request(app)
.get('/api/v2/blah-blah')
.set('authorization', 'Bearer ' + token) // 1) using the authorization header
.expect(200)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) {
return done(err);
}
// some `res.body` assertions...
done();
});
});
it('should respond with status code 200 and so on...', function (done) {
request(app)
.get('/api/v2/blah-blah')
.query({access_token: token}) // 2) using the query string
.expect(200)
.expect('Content-Type', /json/)
.end(function (err, res) {
if (err) {
return done(err);
}
// some `res.body` assertions...
done();
});
});
});
您可能希望有一個輔助函數來驗證用戶身份:
test/auth-helper.js
'use strict';
var request = require('supertest');
var app = require('app.js');
/**
* Authenticate a test user.
*
* @param {User} user
* @param {function(err:Error, token:String)} callback
*/
exports.authenticate = function (user, callback) {
request(app)
.post('/auth/local')
.send({
email: user.email,
password: user.password
})
.end(function (err, res) {
if (err) {
return callback(err);
}
callback(null, res.body.token);
});
};
祝您有個美好的一天!
- 1. 如何使用Passport/Facebook策略驗證Supertest請求/?
- 2. NodeJS Passport身份驗證錯誤請求
- 3. 無法通過Mocha和Supertest進行身份驗證請求
- 4. 如何驗證OAuth請求?
- 5. 如何驗證SOAP請求
- 6. CSRF Supertest請求失敗
- 7. 使用X509證書驗證SOAP請求
- 8. 使用Passport-local-mongoose的錯誤請求
- 9. 如何禁用HttpHandlers的請求驗證?
- 10. 如何聲明使用supertest的貓鼬驗證錯誤?
- 11. 如何使用ASP.NET Core驗證Web請求的SSL證書
- 12. 禁用請求驗證
- 13. Asp.mvc請求驗證
- 14. Laravel請求驗證
- 15. 驗證請求sql
- 16. 驗證空請求
- 17. 使用MvcReCaptcha僅請求驗證碼
- 18. 使用XML進行WCF請求驗證
- 19. 使用Express驗證請求標頭
- 20. 對ajax查詢使用請求驗證?
- 21. 使用OAuth2驗證Google PubSub POST請求
- 22. 使用請求登錄身份驗證
- 23. 使用JAXB的JAX-WS請求驗證
- 24. Laravel 5.4驗證使用表單請求
- 25. 使用Python請求驗證Yelp Fusion API
- 26. 使用設備來驗證HTTP請求
- 27. 如何使用Node和Passport驗證非空字段?
- 28. 如何使用node.js通過get-request Passport進行身份驗證?
- 29. 如何使用Node.js/Express + Passport + Websockets進行身份驗證?
- 30. 如何使用Laravel Passport在Angular 2中創建身份驗證?
使用此方法我需要運行測試服務器。有可能與Supertest的服務器一起使用嗎? 我使用會話cookie(帶Passport)並且不起作用,我查看user1.post的響應,並且cookie不包含用戶信息 –
您不需要測試服務器。你可以使用你的普通快遞app.js.你有沒有看看[示例](https://github.com/visionmedia/superagent/blob/master/test/node/agency.js)?如果你想把測試保存在一個單獨的文件中,把'require(../ app.js)'放到標題中來啓動你的應用程序。 – zemirco
我得到它的工作,但只有當我殺死已經運行的開發服務器。超級棒,我不必那樣做。任何想法如何使它與superagent很好地發揮?也許聽一個不同的端口用於測試環境? –