Closed mkizka closed 1 year ago
In your config.jest.mjs add this line:
// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testEnvironment: "node", // Edit this line
};
@nicksan222 Thank you! But I got the same result. https://github.com/mkizka/nextjs-serveractions-jest/pull/1
$ cat jest.config.mjs
import nextJest from "next/jest.js";
const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: "./",
});
// Add any custom config to be passed to Jest
/** @type {import('jest').Config} */
const config = {
// Add more setup options before each test is run
// setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testEnvironment: "node",
};
// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
export default createJestConfig(config);
$ yarn test
yarn run v1.22.19
$ jest
- warn You have enabled experimental feature (serverActions) in next.config.js.
- warn Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
FAIL app/action.test.ts
● Test suite failed to run
× To use Server Actions, please enable the feature flag in your Next.js config. Read more: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions#convention
╭─[/home/ubuntu/workspace/nextjs-serveractions-jest/app/action.ts:1:1]
@nicksan222 Thank you! But I got the same result. mkizka/nextjs-serveractions-jest#1
$ cat jest.config.mjs import nextJest from "next/jest.js"; const createJestConfig = nextJest({ // Provide the path to your Next.js app to load next.config.js and .env files in your test environment dir: "./", }); // Add any custom config to be passed to Jest /** @type {import('jest').Config} */ const config = { // Add more setup options before each test is run // setupFilesAfterEnv: ['<rootDir>/jest.setup.js'], testEnvironment: "node", }; // createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async export default createJestConfig(config); $ yarn test yarn run v1.22.19 $ jest - warn You have enabled experimental feature (serverActions) in next.config.js. - warn Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk. FAIL app/action.test.ts ● Test suite failed to run × To use Server Actions, please enable the feature flag in your Next.js config. Read more: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions#convention ╭─[/home/ubuntu/workspace/nextjs-serveractions-jest/app/action.ts:1:1]
I think the issue is related to the fact that server actions are transformed into serverless functions. So it is quite difficult doing a unit testing for those
I suggest you to implement e2e testing tools like cypress or playwright for this job You could then make a separate function with the logic so as to test it with jest
I am experiencing the same issue too. Cant test my form component which calls a server action on submit
Same here
I got the same error, I tried different configurations on next.config.js but nothing seems to work I have two files
app/page.tsx
which has 'use client' directive on the top of the fileactions/submit.ts
which has 'use server' directive on the top of the fileapp/page.tsx
import a server action from actions/submit.ts
and uses it as formAction in a form component.
I'm not trying to test the action itself but only if some components (no action dependent) are loaded in the html
Is there a way to make Jest ignore "use server"
directive at all?
I'm trying to write a unit test for my server actions (no React involved at all), and it cannot import the action if there is "use server"
directive on the top of the file.
myFunction.ts
:
"use server"
const myFunction = () => {}
export default myFunction
myFunction.spec.ts
:
import myFunction from './myFunction'
it('works', async () => {
await myFunction()
})
gives
TypeError: (0 , _myFunction.default) is not a function
The issue is different from the subject, but title is still relevant - I can't test that action because of "use server" directive.
as an alternative solution, it would be cool to mark the test file itself with 'use server'
, but then in my case Jest doesn't see any tests
Something that works for me is to mock the module that uses server (i.e. that has the use server
directive). For example, the component that I want to test (say ComponentA.tsx
) renders a form. It imports a sever action from a file (say the path is @/server/actions.ts
). This is the file that uses use server
directive.
Here's how I test the ComponentA.tsx
:
// ComponentA.spec.tsx
import { postQuestionToServer } from '@/server/actions'
jest.mock('@/server/actions.ts', () => ({
__esModule: true,
postQuestionToServer: jest.fn(), // The server action that is called when the form is submitted
}));
describe('ComponentA', () => {
beforeEach(() => {
(postQuestionToServer as jest.Mock).mockImplementation((data: FormData) => {
return Promise.resolve([]); // or whatever the success value should be
});
});
});
Since I don't really want to send a request to the server, this approach works well for me for unit testing the behavior of the client side component ComponentA
.
Edit: I just realized that the above solution may not help if you want to test that the server action was called, however, you will be able to test other parts of the component.
test('does not work', () => {
const spy = jest.spyOn(formActions, 'postQuestionToServer');
const formEl = screen.getByTestId('my-form');
fireEvent.submit(formEl);
expect(spy).toHaveBeenCalled(); // This will NOT work
})
I encountered exactly the described issue after I updated my package.json packages, so next
was updated to 13.4.19
. After I downgraded it back to "next": "13.4.2",
, all tests continued working.
So the issue must be somewhere between these versions.
When I run jest
, I see the following input:
sergiy@sergiy-macbook project % yarn test
yarn run v1.22.19
$ jest --runInBand
- info Loaded env from /Users/sergiy/Work/project/.env.test.local
- info Loaded env from /Users/sergiy/Work/project/.env.test
- warn You have enabled experimental feature (serverActions) in next.config.js.
- warn Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
So you can see, that it respect serverActions
in jest process in 13.4.2
.
Hope this would help someone
Mocking a server action defined in a "use server" file seems to work perfectly, as long as you specify the entire mock (automock fails). Granted it's not helpful for testing the impact of the action itself.
import { screen } from '@testing-library/react'
import { TodoList } from './TodoList';
import { addTodo } from './actions/addTodo';
jest.mock('./actions/addTodo', () => ({
addTodo: jest.fn(),
}));
describe('TodoList', () => {
it('calls action on submit', async () => {
render(<TodoList />)
fireEvent.input(screen.getByRole('textbox', { name: 'Message' }), { target: { value: 'new todo' }})
fireEvent.click(screen.getByRole('button'))
// wait for todos refreshed from server
await screen.findByText('new todo')
expect(addTodo).toHaveBeenCalledWith({ message: 'new todo' })
})
})
I am getting the same error while trying to run Jest Testing for Server Components:
any idea?
I tried this again with the latest and greatest next.js release (13.5.2), and still get the same message:
`Test suite failed to run
x To use Server Actions, please enable the feature flag in your Next.js config. Read more: https://nextjs.org/docs/app/building-your-application/data-fetching/forms-and-mutations#convention
,-[/Users/craigmcc/Git.Craigmcc/bookcase/src/actions/LibraryActions.ts:1:1]
1 | "use server"
: ^^^^^^^^^^^^
2 |
`
I do indeed have server actions enabled in my next.config.js file:
` /* @type {import('next').NextConfig} / const nextConfig = { experimental: { serverActions: true, }, }
module.exports = nextConfig `
Hi can you upragde to v13.5.4-canary.6 , we land a change in that version to disable the SWC transform and erroring, so you should be able to test the components with basic UI testing tools
Mocking a server action defined in a "use server" file seems to work perfectly, as long as you specify the entire mock (automock fails). Granted it's not helpful for testing the impact of the action itself.
import { screen } from '@testing-library/react' import { TodoList } from './TodoList'; import { addTodo } from './actions/addTodo'; jest.mock('./actions/addTodo', () => ({ addTodo: jest.fn(), })); describe('TodoList', () => { it('calls action on submit', async () => { render(<TodoList />) fireEvent.input(screen.getByRole('textbox', { name: 'Message' }), { target: { value: 'new todo' }}) fireEvent.click(screen.getByRole('button')) // wait for todos refreshed from server await screen.findByText('new todo') expect(addTodo).toHaveBeenCalledWith({ message: 'new todo' }) }) })
Mocking the server actions doesn't help my use case at all ... I am trying to test the actual logic of my server actions, and with the "use server" declaration present, I cannot do so. Without it, those tests (primarily fetch and mutation access to my database) work properly.
Making life even more complicated, though, now I cannot call those server actions in a client side component (which is kind of the point of these things). My current workaround is to create a "shim" module, with "use server" at the top, that just forwards all the calls to the action module that doesn't have this declaration. That is tedious and error prone, but at least I don't have to build and test an API layer to do this (i.e. the kind of thing I have to do with an express-based back end and a front end based on Create React App).
The test is now successful. Thank you!
Yay! v13.5.4-canary.6 fixes it for me as well.
This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.
Verify canary release
Provide environment information
Which area(s) of Next.js are affected? (leave empty if unsure)
App Router, Jest (next/jest)
Link to the code that reproduces this issue or a replay of the bug
https://github.com/mkizka/nextjs-serveractions-jest
To Reproduce
Describe the Bug
I got this message even though serverActions is true. This test passes if I remove "use server".
Expected Behavior
The test succeeds.
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
NEXT-1473