【问题标题】:Angular 2 - test callback to an event in the child componentAngular 2 - 测试子组件中事件的回调
【发布时间】:2016-12-29 10:39:06
【问题描述】:

我有一个包含 1 个子组件的组件。像这样:

<custom-component (customEvent)="foo()"></custom-component>

foo 是一个做事的函数,假设是一个简单的增量。

我想编写一个单元测试,确保在自定义事件发出后,增量确实发生了。

我目前在测试中尝试做的事情是这样的:

let oldValue = component.variableThatShouldBeIncremented;
childComponent.onCustomEvent.emit();
expect(component.variableThatShouldBeIncremented).toBeGreaterThan(oldValue);

这目前不起作用。但是如果我将期望包装在 setTimeout 中,它会这样做。这是有道理的,因为事件是异步的。

我想摆脱 setTimeout。有没有办法告诉“等到事件回调完成”?

我试图寻找示例,但我只找到了检查特定事件是否已发出的测试,而不是检查发出特定事件的结果。

编辑:

我认为 yurzui 的答案是正确的。代码应该可以工作。我通过简化 Q 的代码而犯了一个错误,省略了实际导致问题的代码:foo 函数。

该函数正在从服务中调用一个函数,这不是一个简单的增量。

出于参考目的,我的实际问题是为模拟版本的服务创建的间谍没有在事件处理程序中注册对函数的调用。现在问题解决了

【问题讨论】:

  • 为什么写(customEvent)="foo"而不是(customEvent)="foo()"
  • 抱歉,打错了。我已经编辑了问题:)

标签: unit-testing angular jasmine


【解决方案1】:

它应该工作。您确定使用正确的变量名称吗?例如,如果您有以下模板

<custom-component (customEvent)="foo()"></custom-component>

那么你的输出事件应该是这样的:

@Output('customEvent') onCustomEvent = new EventEmitter();

最后你的测试将通过Plunker Example

it('should work', () => {
  let oldValue = component.variableThatShouldBeIncremented;
  childComponent.onCustomEvent.emit();
  expect(component.variableThatShouldBeIncremented).toBeGreaterThan(oldValue);
});

【讨论】:

  • 我认为这些人在某处订阅了 onCustomEvent 并且在回调中增加 variableThatShouldBeIncremented 并尝试以这种方式测试订阅。
  • @yurzui 是对的。实际上,我在抽象问题时犯了一个错误。我在“foo”函数中实际做的是调用服务(即注入的)。我试图监视该服务的模拟版本,但没有奏效。我最初认为问题与同步有关(这就是我以这种方式创建问题的原因),但实际问题是关于未注册函数调用的间谍。
  • 底线 - 问题出在其他地方,代码应该可以工作。我会将 yurzui 答案标记为正确答案并编辑问题,因此任何其他绊倒此 Q 的访问者都不会被误导。
【解决方案2】:

你需要使用 async 并使用 tick :

在你的测试中:

    it( 'should work', fakeAsync( () => {

        let oldValue = component.variableThatShouldBeIncremented;
        childComponent.onCustomEvent.emit();
        tick(10); // fast forward 10 milliseconds considering that emit would take 10 milliseconds 

          expect(component.variableThatShouldBeIncremented).toBeGreaterThan(oldValue);
    } ) );

顺便说一句,我假设您正在执行增量操作,只是为了查看您的订阅是否正常工作,在这种情况下,更好的处理方法是:

 it( 'should work', fakeAsync( () => {

    childComponent.customEvent.subscribe((data)=>{
       expect(data).toBe('what ever you expect to be emitted');
    });
    childComponent.onCustomEvent.emit();

 } ) );

如果不是,忽略这个。

【讨论】:

  • 您好 Milad,感谢您的回答。我现在发现我的问题实际上是不同的,并且与函数 foo 的实际作用(调用服务而不是增量)有关。通过抽象问题,我隐藏了真正的问题。
猜你喜欢
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 2017-10-10
  • 1970-01-01
相关资源
最近更新 更多