如何在Karma中加载Aurelia插件 [英] How to load an Aurelia plugin in Karma

查看:87
本文介绍了如何在Karma中加载Aurelia插件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ViewModel,它是一个登录确认页面viewmodel:

I've this ViewModel which is a login confirmation page viewmodel:

import { autoinject } from 'aurelia-framework';
import { Router, NavigationInstruction } from 'aurelia-router';
import { ValidationControllerFactory, ValidationController, ValidationRules } from 'aurelia-validation';

import { LoginService } from '../services/login.service';
import { Settings } from '../config/settings';
import { State } from '../services/state';
import { Helpers } from '../services/helpers';

@autoinject
export class Confirm {
    userName: string;
    error: Error;
    controller: ValidationController;
    provider: string;

    constructor(public service: LoginService,
        private router: Router,
        private state: State,
        private helpers: Helpers,
        controllerFactory: ValidationControllerFactory) {
        this.controller = controllerFactory.createForCurrentScope();
        this.provider = this.helpers.getUrlParameter('p');
        this.userName = this.helpers.getUrlParameter('u');
        window.history.replaceState(null, null, '/');
    }

    confirm() {
        this.controller.validate()
            .then(() => {
                this.service.confirm(this.userName)
                    .then(() => {
                        this.router.navigateToRoute('home');
                    })
                    .catch((e: Error) => {
                        if (e.name === 'NullInfo') {
                            this.router.navigateToRoute('login');
                        } else {
                            this.error = e;
                        }
                    });
            })
            .catch(e => this.error = e);
    }
}

ValidationRules
    .ensure((c: Confirm) => c.userName)
    .satisfies((value, obj) => obj.service.exists(value))
    .withMessage('This user name already exists, please choose another one')
    .on(Confirm);

我想使用 aurelia-cli 通过单元测试对其进行测试,我编写了以下规范:

I want to test it by unit test using aurelia-cli, I wrote this specs:

import { Router, NavigationInstruction } from 'aurelia-router';

import { Confirm } from '../../../src/pages/confirm';
import { LoginService } from '../../../src/services/login.service';
import { Settings } from '../../../src/config/settings';
import { State } from '../../../src/services/state';
import { Helpers } from '../../../src/services/helpers';

describe('confirm page spec', () => {
    let service: LoginService;
    let router: Router;
    let state: State;
    let helpers: Helpers;
    let controllerFactory;

    let userName;
    let promise;
    let resolveCallback;
    let rejectCallback;

    beforeEach(() => {
        // mock Promise
        promise = {
            then: r => {
                resolveCallback = r;
                return {
                    catch: e => {
                        rejectCallback = e;
                    }
                }
            }
        };

        // mock LoginService
        service = {
            confirm: u => {
                userName = u;
                return promise;
            }
        } as LoginService;

        // mock Router
        router = {
            navigateToRoute: r => { }
        } as Router;

        state = new State();
        helpers = new Helpers(state);
        spyOn(helpers, 'getUrlParameter')

       // mock controllerFactory
        controllerFactory = {
            createForCurrentScope: () => { }
        };

        spyOn(controllerFactory, 'createForCurrentScope')
            .and.returnValue({
                validate: () => {
                    return promise;
                }
            });
    });

    it('constructor should get url paratemeters', () => {
        // prepare
        spyOn(helpers, 'getUrlParameter');

        // act
        let page = new Confirm(service, router, state, helpers, controllerFactory);

        // verify
        expect(helpers.getUrlParameter).toHaveBeenCalledWith('p');
        expect(helpers.getUrlParameter).toHaveBeenCalledWith('u');
    })
});

当我启动 au test 时,出现此错误:

When I launch au test I get this error :

Chrome 53.0.2785(Windows 7 0.0.0)错误未捕获的错误:您是否 忘记在您的main.js中添加".plugin('aurelia-validation)"?在 C:/Users/olefebvre/Source/Repos/chatle.aurelia/wwwroot/scripts/app-bundle.js:2616

Chrome 53.0.2785 (Windows 7 0.0.0) ERROR Uncaught Error: Did you forget to add ".plugin('aurelia-validation)" to your main.js? at C:/Users/olefebvre/Source/Repos/chatle.aurelia/wwwroot/scripts/app-bundle.js:2616

如何修复?

完整的项目位于github上的 https://github.com/aguacongas/chatle.aurelia

The full project is on github at https://github.com/aguacongas/chatle.aurelia

我试图通过将验证放入自定义元素中来解决此问题(并且因为我在另一页上需要它)
我的组件用户名代码是:

I tried to workaround by put the validation in a custom element (and because I need it on an other page)
My component user-name code is :

<template>
    <div validation-errors.bind="userNameErrors" class.bind="userNameErrors.length ? 'has-error' : ''">
        <input class="form-control" name="UserName" value.bind="userName & validate" />
        <span class="help-block" repeat.for="errorInfo of userNameErrors">
            ${errorInfo.error.message}
        <span>
    </div>
</template>

用户名.ts

import { autoinject, bindable, bindingMode } from 'aurelia-framework';
import { ValidationControllerFactory, ValidationController, ValidationRules } from 'aurelia-validation';

import { LoginService } from '../services/login.service';

@autoinject
export class UserName {
    @bindable({ defaultBindingMode: bindingMode.twoWay })
    userName: string;
    controller: ValidationController;

    constructor(private service: LoginService, controllerFactory: ValidationControllerFactory) { 
        this.controller = controllerFactory.createForCurrentScope();
    }

    userNameAvailable(value: string) {        
        return new Promise<boolean>(resolve => {
            this.service.exists(value)
                .then(r => resolve(!r));
        })
    }
}

ValidationRules
    .ensure((c: UserName) => c.userName)
    .satisfies((value, obj) => obj.userNameAvailable(value))
    .withMessage('This user name already exists, please choose another one')
    .on(UserName);

组件规格为:

import {StageComponent} from 'aurelia-testing';
import {bootstrap} from 'aurelia-bootstrapper';

describe('user-name component specs', () => {
  let component;

  beforeEach(() => {
    component = StageComponent
      .withResources('components/user-name')
      .inView('<user-name userName.bind="firstName"></user-namet>')
      .boundTo({ firstName: 'Test' });
  });

  it('should render first name', done => {
    component.create(bootstrap).then(() => {
      const nameElement = document.querySelector('.form-control');
      expect(nameElement.attributes['value']).toBe('Test');
      done();
    });
  });

  afterEach(() => {
    component.dispose();
  });
});

我运行au test时收到此警告,但未创建组件

when I run au test I receive this warning and the component is not created

WARN:'%c未处理的拒绝错误:您忘记添加了吗? ".plugin('aurelia-validation)"到您的main.js? 在FluentEnsure.assertInitialized( http://localhost:9876/base/wwwroot/scripts/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:197927 ) 在FluentEnsure.ensure( http://localhost:9876/base/wwwroot/scripts/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:196845 ) 在Function.ValidationRules.ensure( http://localhost: 9876/base/wwwroot/scripts/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:198743 ) 在对象. ( http://localhost:9876/base/wwwroot/脚本/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:95049 ) 在Object.execCb( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3785:299 ) 在Object.check( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3774:12 ) 在Object.enable( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3779:58 ) 在Object.enable( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3783:433 ) 在对象. ( http://localhost:9876/base/wwwroot/脚本/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3778:436 ) 在 http://localhost:9876/base/wwwroot/脚本/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3763:140 在y( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3762:207 ) 在Object.enable( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3777:469 ) 在Object.init( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3772:154 ) 在 http://localhost:9876/base/wwwroot/脚本/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3782:308

WARN: '%cUnhandled rejection Error: Did you forget to add ".plugin('aurelia-validation)" to your main.js? at FluentEnsure.assertInitialized (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:197927) at FluentEnsure.ensure (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:196845) at Function.ValidationRules.ensure (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:198743) at Object. (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?f3fa3f9ce9b587af8455ab05a0d491f872123546:9:95049) at Object.execCb (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3785:299) at Object.check (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3774:12) at Object.enable (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3779:58) at Object.enable (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3783:433) at Object. (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3778:436) at http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3763:140 at y (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3762:207) at Object.enable (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3777:469) at Object.init (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3772:154) at http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?8e5718043dfbefd1c3ad0ea29315a48c1ff7a645:3782:308

更新2

根据马修·詹姆斯·戴维斯(Matthew James Davis)的回答,我重写了规范:

UPDATE 2

Based on Matthew James Davis answer, I rewrote the spec:

import { Aurelia } from 'aurelia-framework';
import { StageComponent } from 'aurelia-testing';
import { bootstrap } from 'aurelia-bootstrapper';

describe('user-name component specs', () => {
  let component;

  beforeEach(() => {
    component = StageComponent
      .withResources('components/user-name')
      .inView('<user-name userName.bind="firstName"></user-namet>')
      .boundTo({ firstName: 'Test' });

    // bootstrap function call the component configure function with an Aurelia instance
    component.configure = (aurelia:Aurelia) => {
      aurelia.use
      .standardConfiguration()
      .plugin('aurelia-validation');
    }
  });

  it('should render user name', done => {
    component.create(bootstrap).then(() => {
      const nameElement = document.querySelector('.form-control');
      expect(nameElement['value']).toBe('Test');
      done();
    });
  });

  afterEach(() => {
    component.dispose();
  });
});

但是现在我在加载模块上得到了这个错误:

but now I get this error on load module :

WARN:'%c未处理的拒绝错误:无法解析访问器函数: 功能 (c){__ cov_YrDLEqGJfOMLMH3Hdk8_ZA.f ['231'] ++; __ cov_YrDLEqGJfOMLMH3Hdk8_ZA.s ['724'] ++;返回 c.userName;} 在ValidationParser.getAccessorExpression( http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:177914 ) 在ValidationParser.parseProperty( http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:178586 ) 在FluentEnsure.ensure( http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:196210 ) 在Function.ValidationRules.ensure( http://localhost: 9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:197995 ) 在对象. ( http://localhost:9876/base/wwwroot/脚本/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:94307 ) 在Object.execCb( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3785:299 ) 在Object.check( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3774:12 ) 在Object.enable( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3779:58 ) 在Object.enable( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3783:433 ) 在对象. ( http://localhost:9876/base/wwwroot/脚本/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3778:436 ) 在 http://localhost:9876/base/wwwroot/脚本/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3763:140 在y( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3762:207 ) 在Object.enable( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3777:469 ) 在Object.init( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3772:154 ) 在 http://localhost:9876/base/wwwroot/脚本/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3782:308 从上一个事件: 在DefaultLoader.loadModule( http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:11444:14 )

WARN: '%cUnhandled rejection Error: Unable to parse accessor function: function (c){__cov_YrDLEqGJfOMLMH3Hdk8_ZA.f['231']++;__cov_YrDLEqGJfOMLMH3Hdk8_ZA.s['724']++;return c.userName;} at ValidationParser.getAccessorExpression (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:177914) at ValidationParser.parseProperty (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:178586) at FluentEnsure.ensure (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:196210) at Function.ValidationRules.ensure (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:197995) at Object. (http://localhost:9876/base/wwwroot/scripts/app-bundle.js?4e630e49e067afd65b1f5906dc4064c434c5e5df:9:94307) at Object.execCb (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3785:299) at Object.check (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3774:12) at Object.enable (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3779:58) at Object.enable (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3783:433) at Object. (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3778:436) at http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3763:140 at y (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3762:207) at Object.enable (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3777:469) at Object.init (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3772:154) at http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:3782:308 From previous event: at DefaultLoader.loadModule (http://localhost:9876/base/wwwroot/scripts/vendor-bundle.js?89c5527ca11655b8716186a7a911ca39c4069f47:11444:14)

更新3

好吧,仅当我在业力方面涵盖了app-bundle.js时,才会引发错误,如果我对其进行注释,则不会引发解析器错误:

UPDATE 3

Ok, the error is throw only when I cover app-bundle.js in karma, if I comment it the parser error is not throwed :

preprocessors: {
  [project.unitTestRunner.source]: [project.transpiler.id],
  //[appBundle]: ['coverage']
},

但该值未绑定到输入字段

But the value is not bound to the input field

推荐答案

使用自定义引导程序功能

您使用的代码使用默认的引导程序,该程序会加载默认的aurelia配置.相反,您需要使用与您的main.js相匹配的自定义引导程序.试试这个:

Use a custom bootstrap function

The code you're using uses the default bootstrapper, which loads a default aurelia configuration. Instead, you need to use a custom bootstrapper that matches your main.js. Try this:

it('should render first name', done => {
    component
      .create(
        bootstrap((aurelia) => {
           aurelia.use
            .standardConfiguration()
            .plugin('aurelia-validation');
        })
      ).then(() => {
        const nameElement = document.querySelector('.form-control');
        expect(nameElement.attributes['value']).toBe('Test');
      done();
    });
  });

这篇关于如何在Karma中加载Aurelia插件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆