TESTING Published: 04.2024
Views: 98

>_ Mastering API Testing with Mocking: A Step-by-Step Guide for Beginners

Mastering API Testing with Mocking: A Step-by-Step Guide for Beginners

A comprehensive guide to API testing using Mock Service Worker (MSW). Learn how to write reliable tests by mocking API responses, handling different scenarios, and ensuring consistent test results.

Mastering API Testing with Mocking

Today, we're going to dive into the world of API testing with mocking, and I'll guide you through every step of the process. By the end of this post, you'll have a solid understanding of how to write robust tests without relying on external APIs, ensuring consistent and reliable results.

Key Concepts

Before we begin, let's quickly go over some key concepts:

  • Mocking: Simulating the behavior of real objects or services within a controlled environment, allowing you to isolate and test specific parts of your codebase.
  • Mock Service Worker (MSW): A library that intercepts network requests and returns mocked responses, making it easier to test APIs without relying on actual servers.

Setting Up MSW

npm install msw --save-dev

Creating the Mock Server

import { setupServer } from 'msw/node'
import { http, HttpResponse } from 'msw'

// set up the mock server
const server = setupServer(
  http.get('https://api.tvmaze.com/shows/1', () => {
    return HttpResponse.json({ data: 'test data' })
  })
)

Here, we're using the setupServer function from msw to create a mock server. The http.get method allows us to define how the server should respond to a specific GET request. In this case, we're mocking a successful response for the /shows/1 endpoint, returning a JSON object with the data property set to 'test data'.

Test Setup and Teardown

// start the server before running tests
beforeAll(() => {
  server.listen()
})

// stop the server after running tests
afterAll(() => {
  server.close()
})

The beforeAll and afterAll hooks ensure that the mock server is running during test execution and is properly cleaned up afterwards.

Writing Test Cases

Test Case 1: Successful Response

// test case 1: successful response
test('getData - success', async () => {
  const data = await getData('shows/1')
  expect(data).toEqual({ data: 'test data' })
})

In this test case, we're calling the getData function with the 'shows/1' endpoint and asserting that the returned data matches the mocked response.

Test Case 2: 404 Error

// test case 2: 404 (Not Found) error
test('getData - not found', async () => {
  server.use(
    http.get('https://api.tvmaze.com/shows/2', () => {
      return new HttpResponse(null, { status: 404, statusText: 'Not Found' })
    })
  )
  const data = await getData('shows/2')
  expect(data).toEqual(new Error('Endpoint not found'))
})

Here we're mocking a 404 (Not Found) error response and verifying error handling.

Test Case 3: Server Error

// test case 3: 500 (Server Error)
test('getData - server error', async () => {
  server.use(
    http.get('https://api.tvmaze.com/shows/2', () => {
      return new HttpResponse(null, { status: 500, statusText: 'Not Found' })
    })
  )
  const data = await getData('shows/2')
  expect(data).toEqual(new Error('An error occurred while fetching data'))
})

Similar to the previous case, but testing server error scenarios.

Test Case 4: Generic Error

// test case 4: generic error response
test('getData - error', async () => {
  server.use(
    http.get('https://api.tvmaze.com/fake', () => {
      return HttpResponse.error()
    })
  )
  const data = await getData('fake')
  expect(data).toMatchObject({ status: 'error' })
})

This final case tests generic error handling using HttpResponse.error().

Conclusion

By mocking the API responses with MSW, we can test our code's behavior without relying on actual external APIs, ensuring our tests are reliable and consistent across different environments. Remember, writing tests is crucial for maintaining a robust and maintainable codebase!

TAGS:
MOCKING SPYING MSW