-
-
Notifications
You must be signed in to change notification settings - Fork 251
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Testing with api routes? #130
Comments
Hey there @tettoffensive:
Could you create a CodeSandbox/reproduction repository to test that?
That I don't know either, it would depend what you're expecting but when testing usually you're not using a real browser, it means that the cookies even if set on the http response will not be stored in the requester (your testing environment/http library). This would explain your issue. My 2 cents: it seems you're trying to unit test your wrapped API routes. Which means you'll also be unit testing/mocking withIronSession. But withIronSession is already tested so this could lead to weird testing code (hard to test) or duplicate testing. I would do this instead:
Maybe there's something missing in the library withIronSession to ease what you're trying to do, not sure though about what is missing. |
@vvo I ended up creating a mock and in my setup using class MockIronStore {
private static instance: MockIronStore;
private saved: { [key: string]: string | object | number };
private unsaved: { [key: string]: string | object | number };
private constructor() {
this.saved = {};
this.unsaved = {};
}
static getOrCreateStore(): MockIronStore {
if (!MockIronStore.instance) {
MockIronStore.instance = new MockIronStore();
}
return MockIronStore.instance;
}
get(key: string) {
return this.unsaved[key] || undefined;
}
set(key: string, val: string | object | number) {
this.unsaved[key] = val;
}
unset(key: string) {
delete this.unsaved[key];
}
seal() {
this.saved = { ...this.unsaved };
}
clear() {
this.unsaved = {};
}
}
function throwOnNoPassword() {
throw new Error('next-iron-session: Missing parameter `password`');
}
function throwOnNoCookieName() {
throw new Error('next-iron-session: Missing parameter `cookieName`');
}
const applySession = jest.fn().mockImplementation((req) => {
const store = MockIronStore.getOrCreateStore();
const session = {
set: store.set.bind(store),
get: store.get.bind(store),
unset: store.unset,
save() {
store.seal();
},
destroy() {
store.clear();
},
};
req.session = session;
});
export default { MockIronStore };
module.exports = {
throwOnNoCookieName: jest.fn().mockImplementation(),
throwOnNoPassword: jest.fn().mockImplementation(),
applySession,
withIronSession: jest
.fn()
.mockImplementation(
(
withIronSessionWrapperHandler,
{
ttl = 15 * 24 * 3600,
cookieName = throwOnNoCookieName(),
password = throwOnNoPassword(),
cookieOptions = {},
},
) => {
return jest.fn().mockImplementation((...args) => {
const handlerType = args[0] && args[1] ? 'api' : 'ssr';
const req = handlerType === 'api' ? args[0] : args[0].req;
const res = handlerType === 'api' ? args[1] : args[0].res;
applySession(req, res, { ttl, cookieName, password, cookieOptions });
return withIronSessionWrapperHandler(...args);
});
},
),
}; And in my test setup: const res: { session?: Session } = {};
let session: Session;
await applySession(res, undefined, { cookieName: 'test', password: 'test' });
if (res.session) {
session = res.session;
} else {
throw new Error('No session after apply session');
} |
Thanks, closing this then! |
I'm testing some Next.js API routes using the following.
My API route handler is wrapped in a
withIronSession
. And I would like to do something like:My ultimate goal is to have my tests confirm that my login and logout are properly storing/destroying credentials. Maybe the best thing to do is mock
next-iron-session
(though I had problems with that too:TypeError: (0 , _nextIronSession.withIronSession) is not a function
)What would you recommend?
The text was updated successfully, but these errors were encountered: