繁体   English   中英

Angular4-如何使用Karma和Jasmine对指令进行单元测试

[英]Angular4 - how to unit test a directive using Karma and Jasmine

我创建了一个非常简单的指令以用于输入元素,该指令仅应允许输入一个十进制数字(带有单个小数点的数字)。

该指令的定义如下:

import { HostListener, Directive, ElementRef  } from '@angular/core';

// Directive attribute to stop any input, other than a decimal number.
@Directive({
    selector: '[decimalinput]'
})
export class DecimalInputDirective {

    constructor(private element : ElementRef) { }

    // Hook into the key press event.
    @HostListener('keypress', ['$event']) onkeypress( keyEvent : KeyboardEvent ) : boolean {

        // Check if a full stop already exists in the input.
        var alreadyHasFullStop = this.element.nativeElement.value.indexOf('.') != -1;

        // Get the key that was pressed in order to check it against the regEx.
        let input = String.fromCharCode(keyEvent.which);

        // Test for allowed character using regEx. Allowed is number or decimal.
        var isAllowed = /^(\d+)?([.]?\d{0,2})?$/.test( input );

        // If this is an invlid character (i.e. alpha or symbol) OR we already have a full stop, prevent key press.
        if (!isAllowed || (isAllowed && input == '.' && alreadyHasFullStop)){
            keyEvent.preventDefault();
            return false;
        }

        return true;
    }
}

该指令应允许"123.123"而不是"abc""1.2.1" 现在,我想测试该指令,在线阅读,到目前为止,我已经提出了这个建议:

import { Component, OnInit, TemplateRef,DebugElement, ComponentFactory, ViewChild, ViewContainerRef } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { DecimalInputDirective } from './decimalinput.directive';
import { By } from '@angular/platform-browser';

@Component({
    template: `<input type="text" name="txtDecimalTest" decimalinput>` 
})
class TestDecimalComponent { }


describe('Directive: DecimalInputDirective', () => {

    let component: TestDecimalComponent;
    let fixture: ComponentFixture<TestDecimalComponent>;
    let decimalInput: DebugElement;

    beforeEach(() => {

      TestBed.configureTestingModule({
        declarations: [TestDecimalComponent]
      });

      fixture = TestBed.createComponent(TestDecimalComponent);
      component = fixture.componentInstance;
      decimalInput = fixture.debugElement.query(By.css('input[name=txtDecimalTest]'));
    });

    it('Entering email and password emits loggedIn event', () => {

        // This sets the value (I can even put "abc" here and it will work.
        decimalInput.nativeElement.value = "12345";

        // But I am trying to initialize the keypress event, so the character is tested in a real world way when the user is using.
        decimalInput.nativeElement.dispatchEvent(new KeyboardEvent("keypress", { key: "a" })); // Nothing happens here!  This was my attempt...

        // This 
        expect(decimalInput.nativeElement.value).toBe("12345");
    });
});

您可以从代码中看到以下行:

decimalInput.nativeElement.dispatchEvent(new KeyboardEvent...

是我尝试模拟按键,就像用户正在输入一样。 如果我模拟了a,然后是b,然后是c,然后是1,然后是2,然后是3,则我希望测试能够确保该值仅是“ 123”,并且在指令的工作方式中被忽略了“ abc”。

两个问题-1)这是我应该做的正确测试吗? 2)我的代码有什么问题-为什么模拟按键不执行任何操作?

感谢您提前提出任何建议! :)

通常,以某种方式对指令进行测试,以便将其用于实际组件中。 因此,您可以创建一个将使用您的指令的伪组件,并且可以测试该组件以处理您的指令。

这是大多数人建议的。

因此,在测试文件中创建一个伪指令

// tslint:disable-next-line:data
@Component({
  selector: 'sd-test-layout',
  template: `
    <div sdAuthorized [permission]="'data_objects'">test</div>`
})
export class TestDecimalInputDirectiveComponent {

  @Input() permission;

  constructor() {
  }
}

然后,在您每次使用TestBed之前创建组件实例,现在您可以应用鼠标事件并在实际情况下对其进行测试

TestBed.configureTestingModule({
  imports: [
    HttpModule,
    SharedModule
  ],
  declarations: [
    TestDecimalInputDirectiveComponent,
  ],
  providers: [
    {
      provide: ElementRef,
      useClass: MockElementRef
    },
    AuthorizedDirective,
  ]
}).compileComponents();

只是给你提示。 您可以点击此链接获取更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM