如何对 Angular 2 中的指令进行单元测试?
How to Unit Test a Directive In Angular 2?
问题: 我希望能够 对 Angular 2 中的指令进行单元测试,以确保它可以正确编译。
在Angular 1 中,可以使用$compile(angular.element(myElement)
服务并在之后调用$scope.$digest()
。我特别希望能够在单元测试中执行此操作,这样我就可以测试 Angular 在 my-attr-directive
编译的代码中 <div my-attr-directive/>
结束时 运行。
约束条件:
- Angular 2 使用 JAVASCRIPT。所有有点相关的来源似乎都需要 TS。 Perhaps this resource truly does solve the problem我对TS的理解也很薄弱
- Jasmine 中的单元测试
- 一定不能太老套以至于我的单元测试最终会失败。参见 a related SO post on compiling HTML manually in Angular 2
使用 TestBed 测试编译指令
假设您有以下指令:
@Directive({
selector: '[my-directive]',
})
class MyDirective {
public directiveProperty = 'hi!';
}
您需要做的是创建一个使用该指令的组件(它可以仅用于测试目的):
@Component({
selector: 'my-test-component',
template: ''
})
class TestComponent {}
现在您需要创建一个声明了它们的模块:
describe('App', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
MyDirective
]
});
});
// ...
});
您可以将模板(包含指令)添加到组件中,但可以通过在测试中覆盖模板来动态处理它:
it('should be able to test directive', async(() => {
TestBed.overrideComponent(TestComponent, {
set: {
template: '<div my-directive></div>'
}
});
// ...
}));
现在您可以尝试编译组件,并使用By.directive
查询它。最后,有可能使用 injector
:
获得指令实例
TestBed.compileComponents().then(() => {
const fixture = TestBed.createComponent(TestComponent);
const directiveEl = fixture.debugElement.query(By.directive(MyDirective));
expect(directiveEl).not.toBeNull();
const directiveInstance = directiveEl.injector.get(MyDirective);
expect(directiveInstance.directiveProperty).toBe('hi!');
});
# 旧答案:
要测试一个指令,您需要用它创建一个假组件:
@Component({
selector: 'test-cmp',
directives: [MyAttrDirective],
template: ''
})
class TestComponent {}
您可以在组件本身中添加模板,但可以通过在测试中覆盖模板来动态处理它:
it('Should setup with conversation', inject([TestComponentBuilder], (testComponentBuilder: TestComponentBuilder) => {
return testComponentBuilder
.overrideTemplate(TestComponent, `<div my-attr-directive></div>`)
.createAsync(TestComponent)
.then((fixture: ComponentFixture<TestComponent>) => {
fixture.detectChanges();
const directiveEl = fixture.debugElement.query(By.css('[my-attr-directive]'));
expect(directiveEl.nativeElement).toBeDefined();
});
}));
请注意,您可以测试呈现的指令,但我找不到以组件的方式测试指令的方法(指令没有 TestComponentBuilder)。
我花了一些时间才找到一个好的例子,angular gitter 频道上的一位好心人指点我查看 Angular Material Design 2 存储库中的示例。您可以找到一个指令测试示例 here。这是 Material 设计 2 的工具提示指令的测试文件。看起来你必须将它作为组件的一部分进行测试。
问题: 我希望能够 对 Angular 2 中的指令进行单元测试,以确保它可以正确编译。
在Angular 1 中,可以使用$compile(angular.element(myElement)
服务并在之后调用$scope.$digest()
。我特别希望能够在单元测试中执行此操作,这样我就可以测试 Angular 在 my-attr-directive
编译的代码中 <div my-attr-directive/>
结束时 运行。
约束条件:
- Angular 2 使用 JAVASCRIPT。所有有点相关的来源似乎都需要 TS。 Perhaps this resource truly does solve the problem我对TS的理解也很薄弱
- Jasmine 中的单元测试
- 一定不能太老套以至于我的单元测试最终会失败。参见 a related SO post on compiling HTML manually in Angular 2
使用 TestBed 测试编译指令
假设您有以下指令:
@Directive({
selector: '[my-directive]',
})
class MyDirective {
public directiveProperty = 'hi!';
}
您需要做的是创建一个使用该指令的组件(它可以仅用于测试目的):
@Component({
selector: 'my-test-component',
template: ''
})
class TestComponent {}
现在您需要创建一个声明了它们的模块:
describe('App', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
MyDirective
]
});
});
// ...
});
您可以将模板(包含指令)添加到组件中,但可以通过在测试中覆盖模板来动态处理它:
it('should be able to test directive', async(() => {
TestBed.overrideComponent(TestComponent, {
set: {
template: '<div my-directive></div>'
}
});
// ...
}));
现在您可以尝试编译组件,并使用By.directive
查询它。最后,有可能使用 injector
:
TestBed.compileComponents().then(() => {
const fixture = TestBed.createComponent(TestComponent);
const directiveEl = fixture.debugElement.query(By.directive(MyDirective));
expect(directiveEl).not.toBeNull();
const directiveInstance = directiveEl.injector.get(MyDirective);
expect(directiveInstance.directiveProperty).toBe('hi!');
});
# 旧答案:
要测试一个指令,您需要用它创建一个假组件:
@Component({
selector: 'test-cmp',
directives: [MyAttrDirective],
template: ''
})
class TestComponent {}
您可以在组件本身中添加模板,但可以通过在测试中覆盖模板来动态处理它:
it('Should setup with conversation', inject([TestComponentBuilder], (testComponentBuilder: TestComponentBuilder) => {
return testComponentBuilder
.overrideTemplate(TestComponent, `<div my-attr-directive></div>`)
.createAsync(TestComponent)
.then((fixture: ComponentFixture<TestComponent>) => {
fixture.detectChanges();
const directiveEl = fixture.debugElement.query(By.css('[my-attr-directive]'));
expect(directiveEl.nativeElement).toBeDefined();
});
}));
请注意,您可以测试呈现的指令,但我找不到以组件的方式测试指令的方法(指令没有 TestComponentBuilder)。
我花了一些时间才找到一个好的例子,angular gitter 频道上的一位好心人指点我查看 Angular Material Design 2 存储库中的示例。您可以找到一个指令测试示例 here。这是 Material 设计 2 的工具提示指令的测试文件。看起来你必须将它作为组件的一部分进行测试。