Testing Stimulus

I see in the issues on GitHub that testing support is being worked on (maybe even done), but it’s undocumented. Can anyone provide direction on how to setup and create tests for a Stimulus application?

Thanks!

1 Like

Here is an example of a test I wrote for a Stimulus controller. The part I don’t love is all the manual/imperative event firing so I’m considering writing a few helper functions to clean that up if possible. The test is written using the Jest testing framework and jsdom to create some DOM in the test.

import mountDOM from 'jsdom-mount';
import {Application as StimulusApp} from 'stimulus';
import LinkBuilderController from '../link-builder';

describe('LinkBuilderController', () => {
  beforeEach(() => {
    mountDOM(`
      <div data-controller="linkBuilder">
        <input id="link" type="text" value="https://www.example.com/?ref=1234" data-target="linkBuilder.link" readonly>
        <input id="foo" type="text" value="" data-target="linkBuilder.param" data-param-key="foo" data-action="input->linkBuilder#update">
        <input id="bar" type="text" value="" data-target="linkBuilder.param" data-param-key="bar" data-action="input->linkBuilder#update">
      </div>
    `);

    const stimulusApp = StimulusApp.start();
    stimulusApp.register('linkBuilder', LinkBuilderController);
  });

  describe('#update', () => {
    it('adds params to the initial url when you type into any param field', () => {
      const linkElem = document.getElementById('link');
      const fooElem = document.getElementById('foo');
      const barElem = document.getElementById('bar');
      const inputEvent = new Event('input');
      fooElem.value = 'fooValue';
      fooElem.dispatchEvent(inputEvent);
      barElem.value = 'barValue';
      barElem.dispatchEvent(inputEvent);

      expect(linkElem.value).toEqual('https://www.example.com/?ref=1234&bar=barValue&foo=fooValue');
    });

    it('cleans up params that have a falsey value', () => {
      const linkElem = document.getElementById('link');
      const fooElem = document.getElementById('foo');
      const barElem = document.getElementById('bar');
      const inputEvent = new Event('input');
      fooElem.value = 'newValue';
      fooElem.dispatchEvent(inputEvent);
      fooElem.value = '';
      fooElem.dispatchEvent(inputEvent);
      barElem.value = 'barValue';
      barElem.dispatchEvent(inputEvent);

      expect(linkElem.value).toEqual('https://www.example.com/?ref=1234&bar=barValue');
    });
  });
});
3 Likes

I’m getting errors when i am trying to use Jest. If I use the baked-in jsdom from Jest when I try to start the stimulusApp I get ReferenceError: MutationObserver is not defined
Any thoughts?

1 Like

Have a look at this issue https://github.com/stimulusjs/stimulus/issues/130. I used Karma JS in a recent project. https://github.com/jwald1/stimulus-tabs

1 Like

Thanks @jwald1! I will look into that. I saw the link you are using and am trying to get puppeteer working with Jest

This example doesn’t seem to work in stimulus 1.1.0. I think it is due to this change here: https://github.com/stimulusjs/stimulus/pull/131/files#diff-7fa7b6ae1b7d8b301aee4602c7b440dfR25

I’m having a bit of trouble finding a work around to get our test suite back up and running.

Thoughts?

    const application = new Application();
    application.router.start();
    application.dispatcher.start();
    application.register('activations--edit', Controller);

Since Stimulus’ handbook doesn’t cover testing and I couldn’t find any good articles about testing Stimulus controllers, I’ve decided to write an article how my team at Booster Stage approached this problem.

You can find the article at https://shime.sh/testing-stimulus.

It uses the same approach described by @AWaselnuk, but goes into detail about how to set everything up. Hopefully, it gives you some direction.

4 Likes

This is a great write up, thank you! I would prefer Stimulus to offer some kind of dependency injection so that tests aren’t reliant on a virtual DOM. Will have a browse through the Stimulus code to see if a PR is possible.

Since there is still no official guide, I wrote a short article about how to unit/integration test Stimulus controllers using built-in node:test, node:assert, and jsdom.
No heavy test runners, no transpilers, no bundlers. Just Node, Stimulus and JSDOM

1 Like