@joystick.js/test

Testing Components

How to test Joystick components using the test.render() method from @joystick.js/test.

To test Joystick components, the @joystick.js/test package includes a special test.render() method for rendering your component's into memory. Once rendered into memory, you can test:

  • That, given some props and user data, the component renders the correct HTML.
  • DOM event listeners behave in the way that you expect.
  • Component methods you've defined behave in the way that you expect.
  • Data you fetch on the component matches your expectations.

By testing in these four areas, you can gain confidence that your UI behaves how you'd expect for your users.

Using the test.render() Method

To generate an in-memory instance of your component for testing, call the test.render() method from @joystick.js/test, passing the path of the component you'd like to test:

/tests/ui/pages/index/index.test.js

import test from '@joystick.js/test';

test.that('the index page renders as expected', async (assert = {}) => {
  const component = await test.render('ui/pages/index/index.js', {
    props: {},
    state: {},
    options: {
      language: 'en-US',
    },
  });

  assert.is(true, true);
});

Above, we've defined a test with the test.that() method and inside of the test's callback, we create a variable component and set it to a call to test.render() (we expect a Promise to be returned so we place async on the callback for our test and prefix our call with await).

To test.render(), as the first argument, we pass the path to the Joystick component we'd like to test: ui/pages/index/index.js. As the second argument, we pass an options object containing the default props, default state, and some render options (here we force the language for this test to be en-US).

In response, we expect to get back an object with a few methods to help us test our component.

Testing Rendered HTML

On the object returned by test.render(), we can retrieve the rendered HTML for the component by calling to component.instance.render_to_html() on the component instance object returned by test.render():

/tests/ui/pages/index/index.test.js

import test from '@joystick.js/test';

test.that('the index page renders as expected', async (assert = {}) => {
  const component = await test.render('ui/pages/index/index.js', {
    props: {},
    state: {},
    options: {
      language: 'en-US',
    },
  });

  const html = component.instance.render_to_html();

  assert.is(html?.includes('A full-stack JavaScript framework for building web apps and websites.'), true);
});

When we call to component.instance.render_to_html() we expect to get back a string of HTML returned from calling the component's render() method internally.

Testing DOM Events

When testing DOM events in Joystick, focus on side effects. For example, if a click event sets the current time on state, trigger that event and then confirm the value changed:

/tests/ui/pages/index/index.test.js

import test from '@joystick.js/test';

test.that('a button click sets the current time on state', async (assert = {}) => {
  const component = await test.render('ui/pages/index/index.js', {
    props: {},
    state: {},
    options: {
      language: 'en-US',
    },
  });

  component.test.event('click', 'button');

  assert.is(!!component.state.current_time, true);
});

Testing Component Methods

To test custom component methods, use component.test.method():

/tests/ui/pages/index/index.test.js

import test from '@joystick.js/test';

test.that('the reverse_name() method reverses the name', async (assert = {}) => {
  const component = await test.render('ui/pages/index/index.js', {
    props: {},
    state: {},
    options: {
      language: 'en-US',
    },
  });

  const reversed_name = component.test.method('reverse_name', ['Ryan']);

  assert.is(reversed_name === 'nayR', true);
});

Testing Data

To verify data returned from a component’s data() function, use component.test.data():

/tests/ui/pages/index/index.test.js

import test from '@joystick.js/test';

test.that('the data returned matches our expectations', async (assert = {}) => {
  const component = await test.render('ui/pages/index/index.js', {
    props: {},
    state: {},
    options: {
      language: 'en-US',
    },
  });

  const data = await component.test.data();

  assert.is(typeof data?.stars === 'integer', true);
});

API

test.render()

test.render(component_path: string, render_options: object) => object;

Parameters

component_path string required
The path to a component in the project to render into memory.
render_options object
An object of options for customizing the render.