我的目标
我尝试在jest beforeEach()
中使用supertest的agent
函数在每次测试之前登录用户,因为我希望每个测试都在假设用户已登录的情况下运行。
这是我尝试的(为了简洁起见,部分内容被删除):
测试文件:
import { agent, SuperAgentTest } from 'supertest';
import app from '../../src/app';
// create a `testRequest` variable to use in the tests
// that will be refreshed in between
let testRequest: SuperAgentTest;
const fakeUser = { email: 'john@john', username: 'john', password: 'john' };
beforeEach(async () => {
// create new agent
testRequest = agent(app);
// register and login
await testRequest.post('/register').send(fakeUser).expect(302);
// other irrelevant stuff...
});
// protected route
describe('POST /campgrounds/new', () => {
it('returns 200 OK', () => {
return testRequest.get('/campgrounds/new');
})
});
/register
路由:
router.post('/register', async (req, res) => {
const { password, ...details } = req.body;
try {
// I am using passport-local-mongoose for this function-
// it just registers the user
const user = await User.register(new User(details), password);
req.login(user, (err) => {
// error handling and redirect
});
} catch (e) {
// error handling
}
})
这是我的成果
我得到的不是200状态,而是302状态,这意味着我被重定向到登录页面。为了调试这个,我创建了一个名为/current
的测试路由,它将记录当前用户和会话ID cookie。然后我分别在it
和beforeEach
函数中向这个路由发送GET
请求。
有趣的是,它们都记录了相同的会话ID,但只有beforeEach
中的请求具有附加到请求的用户对象。
2条答案
按热度按时间j9per5c41#
#1确保body解析器顺序正确
确保你在任何路由或与auth-related的东西之前有这个。
#2检查Passport中间件连线
确保在任何
app.use('/', aRouter)
、router.get
、router.post
等之前调用app.use(passport.initialize())
和app.use(passport.session())
:编辑:
req.user
的注意事项Passport设计用于在会话中存储用户ID。
每个对服务器的请求都必须从数据库中重新加载用户,这是中间件
passport.initialize()
和passport.session()
的工作。这里的逻辑将调用
passport.deserializeUser
来按ID查找用户,该ID与passport.serializeUser
登录会话时保存的ID相同。为了调试这个问题,我将重点放在
passport.deserializeUser
回调上,在DB查询前后添加日志。(Note:我已经有几年没有教过这个了。如果我没有使用精确的术语,请道歉,等等。)
djmepvbi2#
首先,要理解supertest包不附带会话管理,这是你面临的挑战。另外,还有一个supertest-session可以用来管理会话。
})