unit-testingaureliacustom-elementbindable

Testing aurelia customElement with bindable and dependencies


Im using the 1.0.0-beta.1 of Aurelia and try to write some unit tests.

I have a customElement like this:

...
@inject(BindingEngine, Class1, Class2)
export class MyElement{

@bindable data;

constructor (bindingEngine, class1, class2) {
    ...
}
...

And i want to create a testable instance of MyElement with Mocks of Class1&Class2 and working bindable-field data.

What i found out - so far - is, that the examples with BehaviorInstance no longer work due to API changes described here.

After looking in the Tests from aurelia-templating, my approach now looks some kind like this:

import {TemplatingEngine} from 'aurelia-templating';
import {Container} from 'aurelia-dependency-injection';
import {BindingEngine} from 'aurelia-binding';

import { Class1Mock, Class2Mock } from './myMocks';

describe('The MyElement customElement', () => {
    let container;
    let bindingEngine;
    let templateEngine;

    let myElement;

    beforeEach(() => {
        container = new Container();

        //Add my mocks to DI container?
        container.registerInstance('Class1', new Class1Mock());
        container.registerInstance('Class2', new Class2Mock());

        templateEngine = container.get(TemplatingEngine);
        bindingEngine  = container.get(BindingEngine);

        myElement = templateEngine.createViewModelForUnitTest(MyElement);
    }

    it('should be initialized', (done) => {

        expect(myElement).not.toBe(null);
        expect(myElement).not.toBe(undefined);
        done();
    });
}

It fails already at requesting the bindingEngine from the DI Container or when left out at creating the MyElement-VieModel

Error: Error invoking TaskQueue. Check the inner error for details.
    ------------------------------------------------
    inner error: TypeError: _aureliaPal.DOM.createMutationObserver is not a function
        at makeRequestFlushFromMutationObserver (.../jspm_packages/npm/aurelia-task-queue@1.0.0-beta.1/aurelia-task-queue.js:13:36)
        at new TaskQueue (.../jspm_packages/npm/aurelia-task-queue@1.0.0-beta.1/aurelia-task-queue.js:59:41)
        at Object.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:334:14)
        at InvocationHandler.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:309:168)
        at Container.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:557:25)
        at StrategyResolver.get (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:145:37)
        at Container.get (../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:488:41)
        at Object.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:354:33)
        at InvocationHandler.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:309:168)
        at Container.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:557:25)
        at StrategyResolver.get (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:145:37)
        at Container.get (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:488:41)
        at Object.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:354:33)
        at InvocationHandler.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:309:168)
        at Container.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:557:25)
        at StrategyResolver.get (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:145:37)
        at Container.get (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:488:41)
        at new AggregateError (.../jspm_packages/npm/aurelia-pal@1.0.0-beta.1/aurelia-pal.js:20:13)
        at Container.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:559:15)
        at Object.invoke (.../jspm_packages/npm/aurelia-dependency-injection@1.0.0-beta.1/aurelia-dependency-injection.js:344:33)

So, how do i do this thing right ?

------ Edit:

The Answer from Michael Malone works perfect. For anybody, who come to this question, this is how my example works:

import {TemplatingEngine} from 'aurelia-templating';
import {Container} from 'aurelia-dependency-injection';
import {BindingEngine} from 'aurelia-binding';
import {initialize} from 'aurelia-pal-browser';

import { Class1Mock, Class2Mock } from './myMocks';

describe('The MyElement customElement', () => {
    let container;
    let bindingEngine;
    let templateEngine;

    let myElement;

    initialize();

    beforeEach(() => {
        container = new Container();

        //Add my mocks to DI container?
        container.registerInstance('Class1', new Class1Mock());
        container.registerInstance('Class2', new Class2Mock());

        templateEngine = container.get(TemplatingEngine);
        bindingEngine  = container.get(BindingEngine);

        myElement = templateEngine.createViewModelForUnitTest(MyElement);
    }

    it('should be initialized', (done) => {

        expect(myElement).not.toBe(null);
        expect(myElement).not.toBe(undefined);
        done();
    });
}

Solution

  • Somewhere in your tests, you need to do this:

    import {initialize} from 'aurelia-pal-browser';
    
    initialize();
    

    (as it's executed inline, it just needs to be somewhere in your tests. We have it in a separate initialize.spec.js file)