Unit Testing Aurelia Custom Elements

Aurelia 1

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.

Aurelia Documentation Finally Arrives

In the continued week that is Aurelia Week, the team have been drip releasing tasty little morsels of Javascript framework goodness. The biggest thing …

Aurelia Beta Released

Yes, this is really happening. Aurelia has officially put out its first beta release dubbed beta 1. Just a little over a week ago the team put out a …

Aurelia Pre-Beta Release

The calm before the awesome storm? Rob and the rest of the Aurelia team have put out a pre-beta release which is action packed with a heap of new …

Angular 1.x Concepts In Aurelia

If you’re like me, you’ve worked with Angular a lot or you are currently working with Angular and over time you have grown accustomed to …