📖 Scenario: You are building a simple Next.js 14 app that lets users submit feedback. You want to test the server action that saves the feedback to ensure it works correctly.
🎯 Goal: Create a server action function to save feedback, then write a test to verify it saves the data as expected.
📋 What You'll Learn
Create a server action function called saveFeedback that accepts a feedback string parameter
Create a test file that imports saveFeedback
Write a test case that calls saveFeedback with a sample string and checks the result
Use Next.js 14 server action patterns and modern testing syntax
💡 Why This Matters
🌍 Real World
Server actions in Next.js 14 let you write backend logic that can be tested independently, improving app reliability.
💼 Career
Testing server actions is a key skill for Next.js developers to ensure backend code works correctly and prevents bugs in production.
Progress0 / 4 steps
1
Create the server action function
Create a server action function called saveFeedback in a file named actions.ts. It should accept a single parameter feedback of type string and return an object with a message property set to `Feedback received: ${feedback}`.
NextJS
Hint
Use an async function that returns an object with a message string using a template literal.
2
Set up the test file
Create a test file named actions.test.ts. Import the saveFeedback function from ./actions. Also, import describe, it, and expect from vitest.
NextJS
Hint
Use import statements to bring in saveFeedback and testing functions from vitest.
3
Write a test case for the server action
Inside the test file, write a test case using describe and it. The test should call saveFeedback with the string 'Great app!' and use expect to check that the returned object's message property equals 'Feedback received: Great app!'.
NextJS
Hint
Use await to call saveFeedback and expect(...).toBe(...) to check the message.
4
Complete the test setup with export
Ensure the test file exports nothing extra and the server action remains exported. Confirm the test file ends with the test suite code and the saveFeedback function is exported from actions.ts.
NextJS
Hint
No extra exports needed. Just confirm the function and tests are present as before.
Practice
(1/5)
1. What is the main purpose of testing server actions in Next.js?
easy
A. To catch bugs early and ensure backend reliability
B. To improve frontend styling and layout
C. To speed up client-side rendering
D. To reduce the size of JavaScript bundles
Solution
Step 1: Understand server actions role
Server actions handle backend logic and data processing in Next.js.
Step 2: Identify testing benefits
Testing server actions helps find bugs early and keeps backend code reliable.
Final Answer:
To catch bugs early and ensure backend reliability -> Option A
Quick Check:
Testing server actions = catch bugs early [OK]
Hint: Testing server actions = backend reliability focus [OK]
Common Mistakes:
Confusing server action testing with frontend styling
Thinking testing speeds up rendering
Assuming testing reduces bundle size
2. Which of the following is the correct way to import a server action for testing in Next.js using Vitest?
easy
A. require('myAction') from '@/app/actions';
B. const myAction = import('@/app/actions');
C. import myAction from 'vitest';
D. import { myAction } from '@/app/actions';
Solution
Step 1: Recall ES module import syntax
Next.js and Vitest use ES modules, so import uses 'import { name } from path'.
Step 2: Check each option
import { myAction } from '@/app/actions'; uses correct syntax. require('myAction') from '@/app/actions'; mixes require and import wrongly. import myAction from 'vitest'; imports from wrong module. const myAction = import('@/app/actions'); uses dynamic import incorrectly for testing.
Final Answer:
import { myAction } from '@/app/actions'; -> Option D
Quick Check:
Correct ES import syntax = import { myAction } from '@/app/actions'; [OK]
Hint: Use ES module import syntax for server actions [OK]
Common Mistakes:
Using CommonJS require instead of import
Importing from wrong module
Using dynamic import without await
3. Given this server action test code snippet, what will be the output?
import { describe, it, expect } from 'vitest';
import { addNumbers } from '@/app/actions';
describe('addNumbers', () => {
it('adds two numbers correctly', () => {
const result = addNumbers(2, 3);
expect(result).toBe(5);
});
});
medium
A. Test fails because addNumbers returns a string
B. Test fails because addNumbers is asynchronous
C. Test passes because 2 + 3 equals 5
D. Test throws syntax error due to missing async
Solution
Step 1: Analyze the test function
The test calls addNumbers(2, 3) and expects 5.
Step 2: Check function behavior
If addNumbers adds numbers synchronously, result is 5, so test passes.
Final Answer:
Test passes because 2 + 3 equals 5 -> Option C
Quick Check:
2 + 3 = 5 test passes [OK]
Hint: Check if function returns expected value synchronously [OK]
Common Mistakes:
Assuming function is async without evidence
Confusing return types
Expecting syntax errors without cause
4. You wrote this test for a server action but it fails with a runtime error. What is the likely cause?
import { it, expect } from 'vitest';
import { fetchData } from '@/app/actions';
it('fetches data successfully', () => {
const data = fetchData();
expect(data).toHaveProperty('id');
});
medium
A. expect syntax is invalid for property check
B. fetchData is asynchronous but test lacks async/await
C. fetchData is not imported correctly
D. vitest cannot test server actions
Solution
Step 1: Identify function type
fetchData likely returns a Promise because it fetches data asynchronously.
Step 2: Check test function
Test does not use async/await, so it tries to check a Promise directly, causing runtime error.
Final Answer:
fetchData is asynchronous but test lacks async/await -> Option B
Quick Check:
Async function needs async/await in test [OK]
Hint: Async server actions need async/await in tests [OK]
Common Mistakes:
Forgetting async keyword in test
Checking Promise directly without await
Assuming import error without evidence
5. You want to test a server action that creates a user and returns the user ID. The action throws an error if the username is empty. Which test cases should you write to cover both success and error scenarios?
hard
A. Test with a valid username expecting an ID, and test with empty username expecting an error
B. Test only with a valid username expecting an ID
C. Test with empty username expecting a success response
D. Test with invalid username expecting a null return
Solution
Step 1: Identify success scenario
Valid username should create user and return ID, so test this case.
Step 2: Identify error scenario
Empty username causes error, so test that error is thrown properly.
Final Answer:
Test with a valid username expecting an ID, and test with empty username expecting an error -> Option A
Quick Check:
Cover success and error cases in tests [OK]
Hint: Always test success and error cases for server actions [OK]
Common Mistakes:
Testing only success cases
Expecting success on invalid input
Ignoring error throwing behavior
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.