Bird
Raised Fist0
NextJSframework~20 mins

Testing server actions in NextJS - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Next.js Server Actions Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What is the output when a server action updates state in Next.js 14?

Consider a Next.js 14 component using a server action to update a counter. What will the displayed counter value be after clicking the button once?

NextJS
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  async function increment() {
    'use server';
    setCount(count + 1);
  }

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </>
  );
}
AThe code throws a runtime error because setCount cannot be called inside a server action.
BThe count increases by 1 and displays the updated value immediately.
CThe count stays at 0 because server actions cannot directly update client state.
DThe count increases but only after a full page reload.
Attempts:
2 left
💡 Hint

Remember that server actions run on the server and cannot directly update client state hooks.

📝 Syntax
intermediate
1:30remaining
Which option correctly defines a server action in Next.js 14?

Identify the correct syntax to define a server action function in Next.js 14.

Afunction saveData() { 'use server'; /* logic */ }
Bfunction saveData() { 'use client'; /* logic */ }
Casync function saveData() { 'use client'; /* logic */ }
Dasync function saveData() { 'use server'; /* logic */ }
Attempts:
2 left
💡 Hint

Server actions must be async and include the 'use server' directive.

🔧 Debug
advanced
2:30remaining
Why does this server action cause a hydration mismatch error?

Given this Next.js 14 component with a server action, why does the browser console show a hydration mismatch error?

NextJS
import { useState } from 'react';

export default function Toggle() {
  const [on, setOn] = useState(false);

  async function toggle() {
    'use server';
    setOn(!on);
  }

  return (
    <>
      <p>{on ? 'ON' : 'OFF'}</p>
      <button onClick={toggle}>Toggle</button>
    </>
  );
}
ABecause the server action tries to update client state, causing mismatch between server and client HTML.
BBecause the button's onClick handler is not async, causing event issues.
CBecause useState cannot be used inside Next.js components.
DBecause the component is missing a key prop on the button element.
Attempts:
2 left
💡 Hint

Think about how server actions and client state interact during rendering.

❓ state_output
advanced
2:00remaining
What is the value of count after this server action completes?

In this Next.js 14 component, what will be the value of count after clicking the button once?

NextJS
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  async function increment() {
    'use server';
    // pretend to save to database
    return count + 1;
  }

  return (
    <>
      <p>Count: {count}</p>
      <button onClick={async () => {
        const newCount = await increment();
        setCount(newCount);
      }}>Increment</button>
    </>
  );
}
A1
B0
CNaN
Dundefined
Attempts:
2 left
💡 Hint

Note how the server action returns a value and the client updates state with it.

🧠 Conceptual
expert
2:30remaining
Which statement about Next.js 14 server actions is TRUE?

Select the true statement about server actions in Next.js 14.

AServer actions can directly modify client React state hooks like useState.
BServer actions run on the server and can be called from client components to perform server-side logic.
CServer actions must be synchronous functions without async/await.
DServer actions automatically update client UI without any client-side state management.
Attempts:
2 left
💡 Hint

Think about where server actions run and how they interact with client components.

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

  1. Step 1: Understand server actions role

    Server actions handle backend logic and data processing in Next.js.
  2. Step 2: Identify testing benefits

    Testing server actions helps find bugs early and keeps backend code reliable.
  3. Final Answer:

    To catch bugs early and ensure backend reliability -> Option A
  4. 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

  1. Step 1: Recall ES module import syntax

    Next.js and Vitest use ES modules, so import uses 'import { name } from path'.
  2. 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.
  3. Final Answer:

    import { myAction } from '@/app/actions'; -> Option D
  4. 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

  1. Step 1: Analyze the test function

    The test calls addNumbers(2, 3) and expects 5.
  2. Step 2: Check function behavior

    If addNumbers adds numbers synchronously, result is 5, so test passes.
  3. Final Answer:

    Test passes because 2 + 3 equals 5 -> Option C
  4. 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

  1. Step 1: Identify function type

    fetchData likely returns a Promise because it fetches data asynchronously.
  2. Step 2: Check test function

    Test does not use async/await, so it tries to check a Promise directly, causing runtime error.
  3. Final Answer:

    fetchData is asynchronous but test lacks async/await -> Option B
  4. 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

  1. Step 1: Identify success scenario

    Valid username should create user and return ID, so test this case.
  2. Step 2: Identify error scenario

    Empty username causes error, so test that error is thrown properly.
  3. Final Answer:

    Test with a valid username expecting an ID, and test with empty username expecting an error -> Option A
  4. 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 unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard