Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing 有没有办法在Angular2中测试EventEmitter?_Unit Testing_Angular - Fatal编程技术网

Unit testing 有没有办法在Angular2中测试EventEmitter?

Unit testing 有没有办法在Angular2中测试EventEmitter?,unit-testing,angular,Unit Testing,Angular,我有一个使用EventEmitter的组件,当点击页面上的某个人时,就会使用EventEmitter。是否有任何方法可以在单元测试期间观察EventEmitter,并使用TestComponentBuilder单击触发EventEmitter的元素。next()方法并查看发送的内容?如果发射器是@Output(),您可以订阅或绑定它,在父模板中,检查父组件中的绑定是否已更新。 您还可以发送一个单击事件,然后订阅将启动。您的测试可能是: it('点击时应发出',()=>{ const fixtur

我有一个使用EventEmitter的组件,当点击页面上的某个人时,就会使用EventEmitter。是否有任何方法可以在单元测试期间观察EventEmitter,并使用TestComponentBuilder单击触发EventEmitter的元素。next()方法并查看发送的内容?

如果发射器是
@Output()
,您可以订阅或绑定它,在父模板中,检查父组件中的绑定是否已更新。 您还可以发送一个单击事件,然后订阅将启动。

您的测试可能是:

it('点击时应发出',()=>{
const fixture=TestBed.createComponent(MyComponent);
//监视事件发射器
常量组件=fixture.componentInstance;
spyOn(component.myEventMitter,'emit');
//触发点击
const nativeElement=fixture.nativeElement;
const button=nativeElement.querySelector('button');
dispatchEvent(新事件('click'));
fixture.detectChanges();
期望(component.myeventmitter.emit).toHaveBeenCalledWith('hello');
});
当您的组件为:

@组件({…})
类MyComponent{
@输出MyEventMitter=新的EventEmitter();
按钮点击{
this.myEventMitter.emit('hello');
}
}

你可以使用间谍,这取决于你的风格。下面是如何使用间谍轻松查看
emit
是否正在被发射

it('点击时应发出',()=>{
spyOn(component.eventEmitter,'emit');
component.buttonClick();
expect(component.eventEmitter.emit).tohaveBeenCall();
expect(component.eventEmitter.emit).toHaveBeenCalledWith('bar');
});

我需要测试发射阵列的长度。这就是我在其他答案的基础上所做的

expect(component.myEmitter.emit).toHaveBeenCalledWith([anything(), anything()]);

尽管投票率最高的答案是有效的,但它们并没有展示出良好的测试实践,所以我想我会用一些实际的例子来扩展

假设我们有以下简单的组件:

@组件({
选择器:“我的演示”,
模板:`
点击我!
`
})
导出类DemoComponent{
@单击的输出()=新的EventEmitter();
构造函数(){}
buttonClicked():无效{
this.clicked.emit('clicked!');
}
}
该组件是正在测试的系统,监视它的某些部分会破坏封装。角度组件测试应只知道三件事:

  • DOM(通过fixture.nativeElement.querySelector等
    访问)
    
  • @输入
    s和
    @输出
    s的名称;及
  • 协作服务(通过DI系统注入)
任何涉及直接调用实例上的方法或监视组件部分的操作都与实现紧密耦合,并且会给重构增加摩擦-测试加倍只能用于协作者。在这种情况下,由于我们没有合作者,我们不需要任何模拟、间谍或其他双重测试


测试这一点的一种方法是直接订阅发射器,然后调用单击操作(请参阅):

description('DemoComponent',()=>{
let组件:DemoComponent;
let夹具:组件夹具;
beforeach(异步(()=>{
TestBed.configureTestingModule({
声明:[组成部分]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(DemoComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
});
它('单击时应发出',()=>{
let:字符串;
组件。单击。订阅((事件:字符串)=>{
发射=事件;
});
fixture.nativeElement.querySelector('button')。单击();
expect(发出).toBe('clicked!');
});
});
尽管这直接与组件实例交互,但
@Output
的名称是公共API的一部分,因此耦合不太紧密


或者,您可以创建一个简单的测试主机(请参阅),并实际装载您的组件:

@组件({
选择器:“测试主机”,
模板:`
`
})
类TestHostComponent{
lastClick='';
onClicked(值:字符串):void{
this.lastClick=值;
}
}
然后在上下文中测试组件:

description('DemoComponent',()=>{
let组件:TestHostComponent;
let夹具:组件夹具;
beforeach(异步(()=>{
TestBed.configureTestingModule({
声明:[TestHostComponent,DemoComponent]
})
.compileComponents();
}));
在每个之前(()=>{
fixture=TestBed.createComponent(TestHostComponent);
组件=fixture.componentInstance;
fixture.detectChanges();
});
它('单击时应发出',()=>{
fixture.nativeElement.querySelector('button')。单击();
expect(component.lastClick).toBe('clicked!');
});
});

componentInstance
这里是测试主机,因此我们可以确信我们没有过度耦合到我们实际测试的组件。

您能否提供一个plunker来显示您尝试了什么,然后我可以看看添加缺少的部分。因此,如果我喜欢emitter.subscribe(data=>{});如何获得next()输出?完全正确。或者
TestComponent
中的模板有
(其中
someEmitter
@Output()
),那么
TextComponent
属性应该用发送的事件更新。如果我单击的是锚而不是按钮,查询选择器是否只是一个代替按钮?我使用的是与该组件完全相同的东西,但是'expect(value).toBe('hello');'永远不会跑。我不知道这是否是因为它是一个锚。我更新了我的答案,用一个更干净的方法来测试,用间谍而不是真正的发射器,我认为它应该可以工作(这就是我在电子书中实际做的示例)。这非常有效,谢谢!我不熟悉f