Stimulus Discourse

Testing Stimulus


#1

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!


#2

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');
    });
  });
});

In Controller unit tests, should you unit test the HTML?
#3

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?


#4

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


#5

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


#6

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?


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