Unit Testing Aurelia Custom Elements

If you’re a user of Aurelia and you’re writing unit tests, you might have run into some confusion around testing your custom elements, more specifically how you can mock an injected instance of something into a class.

In my case I had a Custom Element which allows me to display a select2 custom select within my application. I was also injecting the Element itself and EventAggregator onto the class using the @inject class decorator.

At the time of writing this, with Aurelia being so new, this kind of information about dependency injection is hard to come by or not really that well explained yet. A few of the concepts in Aurelia are so new to Javascript, that there are not a lot of examples of testing them (especially within Aurelia).

I apologise in advance if this article doesn’t go into too much depth. I am making an assumption that you are already familiar with Aurelia, you have an understanding of decorators and other concepts that Aurelia uses to allow for your apps to be built.

I decided to share this because it took some serious digging through Aurelia’s internals to find out how I can handle injection on a Custom Element class, I couldn’t find any blog posts or documentation on this aspect (that isn’t to say it doesn’t exist, but I couldn’t find it).

For the context of this article, we are going to be working off of the premise of having a custom element class called CustomSelect (supplied below).

src/custom-element.js

import {EventAggregator} from 'aurelia-event-aggregator';
import {bindable, inject, customElement} from 'aurelia-framework';

import $ from 'jquery';
import 'select2';
import 'select2/css/select2.css!'

@customElement('select2')
@inject(Element, EventAggregator)
export class CustomSelect {
    @bindable name = null;
    @bindable selected = false;
    @bindable handler = function() {};
    @bindable options = {};

    constructor(element, eventAggregator) {
        this.element = element;
        this.eventAggregator = eventAggregator;
    }

    attached() {
        $(this.element).find('select').select2({
            minimumResultsForSearch: -1,
            width: '100%'
        }).on('change', (event) => {
            this.changed(event);
        });
    }

    changed(event) {
        var target = event.target;

        this.eventAggregator.publish('select2-'+target.name+'', event);
    }

}

Now lets write our unit test which will take into account the fact we are injecting Element and the EventAggregator for use within our test. We aren’t going for 100% coverage here, but more detailing how we can test custom elements with bindables as well.

test/unit/custom-element.spec.js

// Import our custom element class that we defined earlier
import {CustomSelect} from '../../../src/custom-select';

// Import container and BehaviorInstance for testing
import {Container} from 'aurelia-dependency-injection';
import {BehaviorInstance} from 'aurelia-templating';

describe('the custom select module', () => {
    // References to containers and our element we define later on
    var selectElement;
    var container;

    // Before each test, we set some things up
    beforeEach(() => {
        // Create a global container from the dependency-injection module
        container = new Container().makeGlobal();

        // Register an instance of Element and set it to be a DIV.
        container.registerInstance(Element, '

Conclusion

This is just a taste-tester. I am working on a larger article that will go into detail testing parts of Aurelia like mocking http requests, attributes and other parts of Aurelia that aren’t well documented in the testing department.