Documentation Index
Fetch the complete documentation index at: https://docs.dynamic.xyz/docs/llms.txt
Use this file to discover all available pages before exploring further.
This guide walks you through setting up Jest testing for a Next.js application that uses the Dynamic Labs SDK. You’ll learn how to properly mock Dynamic components and hooks to write effective unit tests.
Prerequisites
- Node.js installed on your machine
- Basic familiarity with Next.js and React Testing Library
- A Dynamic Labs account with an environment ID
Step 1: Create a New Next.js Project
First, create a new Next.js application using the latest version:
npx create-next-app@latest my-test-app
Follow the prompts to set up your project with TypeScript and other preferred options.
Step 2: Install Dynamic Labs SDK
Install the required Dynamic Labs packages:
npm install @dynamic-labs/sdk-react-core @dynamic-labs/ethereum
Step 3: Add Dynamic to Your Application
Open src/app/layout.tsx and add the DynamicContextProvider. Replace <YOUR_ENVIRONMENT_ID> with your actual environment ID from the Dynamic dashboard:
import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import { DynamicContextProvider } from "@dynamic-labs/sdk-react-core";
import { EthereumWalletConnectors } from "@dynamic-labs/ethereum";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
const geistMono = Geist_Mono({
variable: "--font-geist-mono",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<DynamicContextProvider
theme="auto"
settings={{
environmentId: "<YOUR_ENVIRONMENT_ID>",
walletConnectors: [EthereumWalletConnectors],
}}
>
{children}
</DynamicContextProvider>
</body>
</html>
);
}
Open src/app/page.tsx and add the DynamicWidget component:
import { DynamicWidget } from "@dynamic-labs/sdk-react-core";
export default function Home() {
return (
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
<h1>Hello World</h1>
<DynamicWidget />
</div>
);
}
Install Testing Dependencies
Install Jest and React Testing Library along with necessary type definitions:
npm install -D jest jest-environment-jsdom @testing-library/react @testing-library/dom @testing-library/jest-dom ts-node @types/jest
Initialize Jest Configuration
Create a basic Jest configuration file:
Create a jest.config.ts file in your project root with the following configuration:
import type { Config } from "jest";
import nextJest from "next/jest.js";
const createJestConfig = nextJest({
dir: "./",
});
const config: Config = {
coverageProvider: "v8",
testEnvironment: "jsdom",
};
export default createJestConfig(config);
Set Up Jest Custom Matchers
Create a jest.setup.ts file in your project root to configure testing utilities:
import "@testing-library/jest-dom";
Update Jest Configuration
Update your jest.config.ts to include the setup file:
import type { Config } from "jest";
import nextJest from "next/jest.js";
const createJestConfig = nextJest({
dir: "./",
});
const config: Config = {
coverageProvider: "v8",
testEnvironment: "jsdom",
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
};
export default createJestConfig(config);
Step 5: Write Tests for Dynamic Components
Test the Layout Component
Create a __tests__/layout.test.jsx file to test your layout:
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import Layout from "../src/app/layout";
// Mock the Dynamic SDK components to isolate layout logic in tests
jest.mock("@dynamic-labs/sdk-react-core", () => ({
DynamicContextProvider: ({ children }) => (
<div data-testid="dynamic-context">{children}</div>
),
}));
// Mock the Ethereum wallet connectors
jest.mock("@dynamic-labs/ethereum", () => ({
EthereumWalletConnectors: [],
}));
// Mock Next.js font imports to avoid font loading issues in tests
jest.mock("next/font/google", () => ({
Geist: () => ({ variable: "--font-geist-sans" }),
Geist_Mono: () => ({ variable: "--font-geist-mono" }),
}));
describe("Layout", () => {
it("renders Layout with children", () => {
render(<Layout>Hello World</Layout>);
const heading = screen.getByText("Hello World");
const dynamicContext = screen.getByTestId("dynamic-context");
expect(heading).toBeInTheDocument();
expect(dynamicContext).toBeInTheDocument();
});
});
Test the Page Component
Create a __tests__/page.test.jsx file to test your page:
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import Page from "../src/app/page";
// Mock the Dynamic SDK components
jest.mock("@dynamic-labs/sdk-react-core", () => ({
DynamicWidget: () => <div>DynamicWidget</div>,
}));
describe("Page", () => {
it("renders a heading", () => {
render(<Page />);
const heading = screen.getByText("Hello World");
expect(heading).toBeInTheDocument();
});
});
Step 6: Test Components Using Dynamic Hooks
Update Your Page to Use Hooks
Modify src/app/page.tsx to use Dynamic hooks for displaying user information:
"use client";
import {
DynamicWidget,
useDynamicContext,
useIsLoggedIn,
useUserWallets,
} from "@dynamic-labs/sdk-react-core";
export default function Home() {
const { sdkHasLoaded } = useDynamicContext();
const isLoggedIn = useIsLoggedIn();
const userWallets = useUserWallets();
return (
<div className="font-sans grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20">
<h1>Hello World</h1>
<p>SDK has loaded: {sdkHasLoaded ? "Yes" : "No"}</p>
<p>Is logged in: {isLoggedIn ? "Yes" : "No"}</p>
<p>
User wallets:{" "}
{userWallets.length > 0 ? (
userWallets.map((wallet) => (
<span key={wallet.address}>{wallet.address}</span>
))
) : (
<span>No wallets</span>
)}
</p>
<DynamicWidget />
</div>
);
}
Test with Mocked Hooks
Update __tests__/page.test.jsx to properly mock and test Dynamic hooks:
import "@testing-library/jest-dom";
import { render, screen } from "@testing-library/react";
import Page from "../src/app/page";
import {
useDynamicContext,
useIsLoggedIn,
useUserWallets,
} from "@dynamic-labs/sdk-react-core";
// Mock the Dynamic SDK components and hooks
jest.mock("@dynamic-labs/sdk-react-core", () => ({
DynamicWidget: () => <div>DynamicWidget</div>,
useDynamicContext: jest.fn(),
useIsLoggedIn: jest.fn(),
useUserWallets: jest.fn(),
}));
describe("Page", () => {
beforeEach(() => {
useDynamicContext.mockReturnValue({ sdkHasLoaded: true });
useIsLoggedIn.mockReturnValue({ isLoggedIn: false });
useUserWallets.mockReturnValue([]);
});
it("render render No wallets", () => {
render(<Page />);
expect(screen.getByText("No wallets")).toBeInTheDocument();
});
describe("when the has user logged in with wallets", () => {
beforeEach(() => {
useDynamicContext.mockReturnValue({ sdkHasLoaded: true });
useIsLoggedIn.mockReturnValue({ isLoggedIn: true });
useUserWallets.mockReturnValue([{ address: "0x123" }]);
});
it("render the list of wallets", () => {
render(<Page />);
const wallets = screen.getByText("0x123");
expect(wallets).toBeInTheDocument();
});
});
});
Understanding the Mocking Strategy
When testing components that use the Dynamic Labs SDK, the key approach is to mock the SDK modules and hooks:
Mock the Entire Module
Mock @dynamic-labs/sdk-react-core to replace all components and hooks with Jest mock functions:
jest.mock("@dynamic-labs/sdk-react-core", () => ({
DynamicWidget: () => <div>DynamicWidget</div>,
DynamicContextProvider: ({ children }) => children,
useDynamicContext: jest.fn(),
useIsLoggedIn: jest.fn(),
useUserWallets: jest.fn(),
}));
Mock Individual Hooks
Each hook can return different values for different test scenarios:
beforeEach(() => {
useDynamicContext.mockReturnValue({ sdkHasLoaded: true });
useIsLoggedIn.mockReturnValue({ isLoggedIn: false });
useUserWallets.mockReturnValue([]);
});
Running Your Tests
Add a test script to your package.json:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch"
}
}
Run your tests:
Summary
You’ve successfully set up Jest testing for your Next.js application with Dynamic Labs SDK. The key takeaways are:
- Mock the entire
@dynamic-labs/sdk-react-core module to replace components and hooks
- Use
jest.fn() to create mock implementations that can return different values for different test scenarios
- Configure Jest custom matchers from
@testing-library/jest-dom for better test assertions
This testing approach allows you to thoroughly test your application’s behavior without needing to connect to actual wallets or authenticate real users during your test runs.