Closed timgcarlson closed 2 years ago
Hi, this doesn't seem like a next-auth issue but rather one with jest configuration usage. You're using testEnvironment: "jest-environment-jsdom"
which results in using jose
browser module instead of node.
I suggest you test the getServerSideProps
method separately with the following configuration: testEnvironment: "node"
> More here
Has anyone found a better solution than:
As done above in Bryan's mention of this issuue
@AlanPedro what I did was create two different config files, a jest.api.config and jest.client.config, and setup each as a separate jest project in package.json. This resolved my errors without "overriding" anything
another approach is to add this at the beginning of your test file
/**
* @jest-environment node
*/
test('...', () => {
....
});
@timgcarlson Did you ever find an adequate solution?
The proposed solution by the maintainers is not a good one IMO. Splitting your tests into two different environments does not solve the issue of the tests blowing up when you have to test the UI. To avoid this, you need to extract all your UI code into a separate component, then import that component into the page that is using unstable_getServerSession
, and then test the UI component separately. This causes the return statement of your page component to go uncovered, so you need to istanbul ignore
the component return statement to hide it from coverage. All in all, it just feels super hacky.
I've opened a discussion here: https://github.com/nextauthjs/next-auth/discussions/6084. Hopefully, someone out there has come to an elegant solution. If not, I'll have to move all of my session checks to the client, which I really do not want to have to do.
I managed to avoid the solution @elliotgonzalez-lk of having to create duplicate components because I had already mocked unstable_getServerSession
when I was testing getServerSideProps
separately.
I refactored all of my various "next-auth" mocks into my "Global Mocks" file, @/__tests__/test-utils.tsx
, which re-exports the {render}
and other methods from React Testing Library:
// **Global Mocks**
// Any mocks included here, in `@/__tests__/test-utils`, apply to all tests.
// Due to Jest transformer issues, we mock next-auth's useSession hook directly:
export const mockSession = {
expires: new Date(Date.now() + 2 * 86400).toISOString(),
user: { name: "admin" },
}
jest.mock("next-auth/react", () => {
const originalModule = jest.requireActual("next-auth/react")
return {
__esModule: true,
...originalModule,
useSession: jest.fn(() => ({
data: mockSession,
status: "authenticated",
})),
}
})
// Reference: https://github.com/nextauthjs/next-auth/discussions/4185#discussioncomment-2397318
// We also need to mock the whole next-auth package, since it's used in
// our various pages via the `export { getServerSideProps }` function.
jest.mock("next-auth", () => ({
__esModule: true,
default: jest.fn(),
unstable_getServerSession: jest.fn(
() =>
new Promise((resolve) => {
resolve({
expiresIn: undefined,
loggedInAt: undefined,
someProp: "someString",
})
}),
),
}))
// Reference: https://github.com/nextauthjs/next-auth/issues/4866
I'm not using any custom providers; I only test the <SessionProvider>
in a component that uses it explicitly. The only other global mock I set up is to mock out the Next,js router using next-router-mock:
// Mock Next.js's useRouter hook using the "next-router-mock" package:
jest.mock("next/dist/client/router", () =>
jest.requireActual("next-router-mock"),
)
jest.mock("next/dist/shared/lib/router-context", () => {
const { createContext } = jest.requireActual("react")
const router = jest.requireActual("next-router-mock").default
const RouterContext = createContext(router)
return { RouterContext }
})
// Reference: https://github.com/scottrippey/next-router-mock/issues/58#issuecomment-1182861712
Hey @DoctorDerek, I apologize if this is a bit of a noob question, still learning these things.
I have a component <Dashboard />
that is using getServerSideProps
along with getServerSession
inside of it.
I have set up your solution in my global mocks, however, I am still met with the same error when I just try to import the original <Dashboard />
component since it hits that broken import almost immediately. How did you tell jest to to use your global mock rather than that imported version?
Thanks for the help!
@Nashtronaut You have to specifically mock out every single import that doesn't work. My solution was unstable_getServerSession, so if your version is getServerSession you'd need to update it to that.
Environment
Reproduction URL
https://github.com/timgcarlson/next-auth-jest-bug-getServerSession
Describe the issue
Description
The error happens when running Jest tests on any file that uses
unstable_getServerSession
. From what I can tell, there is a dependency being used byunstable_getServerSession
(jose) that Jest cannot transform properly. It appears that it's using the browser build of jose rather than the node version.This occurs when
unstable_getServerSession
is used in getServerSideProps, as shown in the attached repo. The tests fail on the import of the function, so the component is never run by the tests.I have not encountered this issue anywhere else in Next-Auth. I encountered this issue when I converted my uses of
getSession
tounstable_getServerSession
, as recommended when needing to get the session on the server.Example Code
A Page Component that uses
unstable_getServerSession
A test for that page
The full error that occurs when running Jest tests
How to reproduce
npm i
npm run test
A single test was added for the GetServerSessionPage. The test will fail before it can run because it fails on the import of
unstable_getServerSession
.One of the reccommend solutions in the above test error is _"To have some of your "nodemodules" files transformed, you can specify a custom "transformIgnorePatterns" in your config." I included some commented out code in my repo to demonstrate this, but it results in another issue. This may be a dead end though.
module.exports = createJestConfig(customJestConfig)
and then uncomment the lines below itnpm run test
This results in this new error:
Expected behavior
Using
unstable_getServerSession
should not break testing in Jest. What actually happens are the errors described above when running tests on any file that usesunstable_getServerSession
, whether the test uses it or not. Ideally the function should not require any specific configuration to be testable.