Skip to main content
Skip table of contents

Unit tests

All new code that is added to vets-website should be unit tested and unit tests should cover at least 75% of code paths. Write unit tests as you build to make sure your form (or other component) is behaving as you expect and to help guard against future bugs. For example, you might create a unit test file for each page in a form and then test the following scenarios:

  • The correct number of inputs show up when you render the page.

  • The correct number of fields display validation errors if you submit without entering any information.

  • Any conditional logic on the page displays under the correct conditions.

For more detailed information about unit test best practices and an in-depth discussion of how they apply to vets-website, please view this recording of Front End Unit Tests on VA.gov - Best Practices/Q&A Brown Bag Training.

Overview

Unit test file format: file_name.unit.spec.js

Where: Any file_name.unit.spec.js file located in the /src folder. This file is usually located in a test directory close to the code being tested.

When: Run the test locally through npm script commands, during the Github Actions build (Unit), and after merging to main.

The vets-website repo uses:

Unit tests are collocated with the application folder in a test directory that matches the application directory structure:

CODE
- 📂 src
  - 📂 my-application
    - 📂 components
      - MyComponent.jsx
    - 📂 tests
      - 📂 components
        - MyComponent.unit.spec.jsx

Mocha runs any file_name.unit.spec.js file located in the /src folder. This file is usually located in a test directory close to the code being tested.

Unit test conventions

  • Use describe to organize tests by application and feature. Two levels should be adequate depending on the size of the application being tested. Try to avoid nesting deeper than two levels.

  • Use it to describe the unit test:

    • Use active voice.

    • Describe the behavior in terms specific to the unit.

    • Do not abstract the test description with business logic.

    • Recommended:

      • it('truncates the address property when it is longer than 15 characters')

      • it('renders an error when props.errors contains at least one item')

    • Not recommended:

      • it('shortens the address when the user has a long address')

      • it('shows an error when the user is not logged in')

Testing components

Use React Testing Library's render function when testing components.

CODE
import React from 'react';
import { render } from '@testing-library/react';
import MyComponent from '../../components/MyComponent';

describe('MyComponent', () => {
  it('renders', () => {
    ...
    render(<MyComponent />);
    ...
  });
});

If you're using Enzyme, use shallow instead of mount when possible to test components. Always unmount components at the end of the test.

CODE
import React from 'react';
import { mount } from 'enzyme';
import MyComponent from '../../components/MyComponent';

describe('MyComponent', () => {
  it('renders', () => {
    ...
    const form = mount(<MyComponent />);
    ...
    form.unmount();
  });
});

Other utilities

These utilities can be found in platform/testing/unit/helpers.js:

  • mockFetch() - A function to mock the global fetch function and return the value provided in returnVal

    • resetFetch() - Resets the mocked fetch set with mockFetch()

    • mockApiRequest() - Decorated mockFetch() that adds typical API headers to returnVal

    • mockMultipleApiRequests() - Decorated mockFetch() that mocks a fetch call for each response object in an array

CODE
mockFetch(
  new Error('fake error'), // returnVal
  false, // shouldResolve: false returns rejected promise. default is true
);

Note: This utility can be found in platform/utilities/storage/localstorage.js.

  • getLocalStorage() - convenience accessor for local storage and implements a fallback. Useful for stubbing localstorage.

Examples and guides

Libraries

  • mocha.js: Test framework.

  • chai.js: BDD/TDD assertion library.

  • chai-as-promised: Extends Chai with assertions about promises.

  • sinon.js: Standalone test spies, stubs, and mocks.

  • React Testing Library: React Testing Library is a branch of Testing Library that allows users to test their React components through actual DOM nodes instead of rendered instances.

  • Enzyme: Enzyme is a JavaScript Testing utility for React that makes it easier to test your React Components' output. You can also manipulate, traverse, and in some ways simulate runtime given the output.

  • enzyme-adapter-react-16: Enzyme React 16 integration.

  • react-dom: React DOM library needed for testing React components.

  • react-dom/test-utils: Test utilities for React DOM.

  • react-test-renderer: This package provides an experimental React renderer that can be used to render React components to pure JavaScript objects, without depending on the DOM or a native mobile environment.

  • jsdom: A JavaScript implementation of WHATWG DOM and HTML standards, for use with node.js.

  • choma: Random execution order for mocha suites.


JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.