• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

Unit Testing Aurelia Custom Elements

Aurelia 1 · August 13, 2015

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, '<div>');

        // Using our BehaviorInstance we use the createForUnitTest method and supply our custom element created earlier
        selectElement = BehaviorInstance.createForUnitTest(CustomSelect);

        // You might want to add a class stub here so you can listen to events
        selectElement.EventAggregator = {};
    });

    // A test-case that checks if default properties have been defined
    // this just proves we have an instance and can test bindable values on the class
    // These values are defined as @bindable in our custom element class
    it('contains default properties', () => {
        expect(selectElement.name).toEqual(null);
        expect(selectElement.selected).toEqual(false);
        expect(selectElement.handler).toBeDefined();
        expect(selectElement.options).toEqual({});
    });
});

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.

Dwayne

Leave a Reply Cancel reply

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Sagar Thakur
Sagar Thakur
7 years ago

Hi, I want to know is this the approach to follow when you are creating a stub for a class which has other classes like EventAggregator injected on it and also some custom user classes.

Could you provide some information on that?

Thanks,
Sagar

0
Michael Prescott
Michael Prescott
6 years ago

My code is not able to find the Container. I tried npm install aurelia-dependency-injection –save-dev. Is this still relevant?

0
classicalConditioning
classicalConditioning
6 years ago

@Michael Prescott, try importing it from ‘aurelia-framework’ instead

0

Primary Sidebar

Popular

  • Thoughts on the Flipper Zero
  • I Joined Truth Social Using a VPN and Editing Some HTML to Bypass the Phone Verification
  • How To Install Eufy Security Cameras Without Drilling or Using Screws
  • How To Get The Hash of A File In Node.js
  • Wild Natural Deodorant Review
  • The Most Common iPhone Passcodes (and how to guess them)
  • NBN Box Installed Inside of Garage, Where Do You Put The Modem?
  • How to Record With the Neural DSP Quad Cortex in Reaper (DI and USB Recording)
  • How To Paginate An Array In Javascript
  • Improving The Coopers Australian Pale Ale Extract Tin (and other tips)

Recent Comments

  • CJ on Microsoft Modern Wireless Headset Review
  • Dwayne on Microsoft Modern Wireless Headset Review
  • CJ on Microsoft Modern Wireless Headset Review
  • john on Microsoft Modern Wireless Headset Review
  • Dwayne on Why You Should Be Using globalThis Instead of Window In Your Javascript Code

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz