Mocking API Calls in Tests with Nuxt 3

Testing plays a crucial role in the development of robust and reliable applications. When building web applications, particularly those that rely on external APIs, testing API calls becomes essential to ensure the functionality of the application under various scenarios.

In the context of Nuxt 3, a powerful framework for building modern web applications, effectively mocking API calls in tests can streamline the testing process and improve overall code quality. In this article, we'll explore how to mock API calls in tests using when using Nuxt.

Let's start

To effectively mock API calls in tests using Nuxt 3, we can define a mockFetch function using the vi utility provided by vitest . Let's break down the process step by step.

0. Installing Dependencies

Before diving into testing, let's ensure we have the required dependencies installed. We can use npm or yarn to install vitest and @nuxt/test-utils as dev dependencies in our project:

bashCopy codenpm install --save-dev vitest @nuxt/test-utils
# or
yarn add --dev vitest @nuxt/test-utils

These packages provide utilities and testing tools tailored specifically for testing Nuxt applications.

1. Defining the mockFetch Function

In the test file, we utilize the vi.hoisted function to define a mockFetch function. This function will simulate the behavior of an API call during testing.

import {vi} from 'vitest';

// ... 

const {mockFetch} = vi.hoisted(() => ({
  mockFetch: vi.fn()
}));

// ...

Here, vi.fn() creates a Jest mock function, which we assign to mockFetch. This mock function will mimic the behavior of the actual fetch operation.

2. Mocking the useFetch Function

In Nuxt 3, the useFetch function is used to fetch data from APIs. To mock this function in our tests, we employ the mockNuxtImport function provided by Nuxt testing utilities.

import {mockNuxtImport} from "@nuxt/test-utils/runtime";

// ...

mockNuxtImport('useFetch', () => mockFetch);

By passing 'useFetch' as the first argument and a callback function returning mockFetch as the second argument to mockNuxtImport, we instruct Nuxt 3 to replace calls to useFetch with our mocked mockFetch function during testing.

3. Resetting Mocks After Each Test

To ensure isolation and consistency between tests, it's essential to reset any mocks after each test case. We achieve this by calling the mockReset method on mockFetch within the afterEach hook.

// ...

afterEach(() => {
  mockFetch.mockReset();
})

By resetting the mock function after each test, we prevent any unintended interactions or state accumulation that may affect subsequent test cases.

4. Use Case: Testing a Custom Hook

Let's consider a use case where we want to test a custom hook called useSearchTravel, which fetches travel data from an API. Here's how we can mock the API call using mockFetch:

const MOCKED_VALUE = [];

describe("testing something that use useFetch", async () => {

  mockFetch.mockReturnValue({
    data: ref(MOCKED_VALUE)
  });

  // Now you can write your test cases here
  // the result of useFetch will be {data: ref(MOCKED_VALUE)}

});

In this example, MOCKED_VALUE represents the data that we expect to receive from the API call. We use mockReturnValue to simulate the behavior of the API call and return the mocked data.

Wrapping Up

Testing API calls is a crucial aspect of developing web applications, and with Nuxt 3, we have powerful tools and utilities at our disposal to streamline this process. By effectively mocking API calls in tests, we can ensure the reliability and robustness of our applications across different scenarios.

In this article, we explored how to mock API calls in tests using Nuxt 3. We started by installing the necessary dependencies, including vitest and @nuxt/test-utils, which provide utilities tailored for testing within the Nuxt framework. We then delved into defining the mockFetch function and mocking the useFetch function to simulate API responses.

Additionally, we discussed the importance of resetting mocks after each test to maintain test isolation and prevent unintended interactions. Finally, we explored a use case where we tested the API call replacement using the mockNuxtImport function.

Full Code Example:

import { vi } from 'vitest';
import { mockNuxtImport } from '@nuxt/test-utils';

const { mockFetch } = vi.hoisted(() => ({
  mockFetch: vi.fn()
}));

mockNuxtImport('useFetch', () => mockFetch);

afterEach(() => {
  mockFetch.mockReset();
});

const MOCKED_VALUE = [];
describe("test case", async () => {

  mockFetch.mockReturnValue({
    data: ref(MOCKED_VALUE)
  });

  // Now you can write your test cases here
  // the result of useFetch will be {data: ref(MOCKED_VALUE)}

});

By following these techniques and leveraging the provided utilities, developers can write comprehensive tests for their Nuxt 3 applications, ensuring reliability, stability, and confidence in their codebase.