Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/30.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
Angular 模拟可观测不返回值的角度单元测试_Angular - Fatal编程技术网

Angular 模拟可观测不返回值的角度单元测试

Angular 模拟可观测不返回值的角度单元测试,angular,Angular,我的组件返回基于小时的当前班次 export class CurrentTimeComponent { constructor() {} now$: Observable<Date> = timer(0, 1000).pipe( map(() => new Date()), share() ); shift$: Observable<string> = this.now$.pipe( map((now) => {

我的组件返回基于小时的当前班次

export class CurrentTimeComponent {
  constructor() {}

  now$: Observable<Date> = timer(0, 1000).pipe(
    map(() => new Date()),
    share()
  );

  shift$: Observable<string> = this.now$.pipe(
    map((now) => {
      const hour = now.getHours();
      if (hour < 13) {
        return 'early';
      } else if (hour < 20) {
        return 'late';
      } else {
        return 'night';
      }
    })
  );
}

但是,当我调试测试时,
shift$
总是返回当前日期。它是否应该返回我提供的模拟组件(parseISO(…)?

问题在于,组件实例化时会创建可观察的
shift$
。创建时,它使用创建时的
this.now$
值,这是
now$
初始化为的
计时器

因此,在您的测试中,当您重新定义
组件时。现在$
成为一个不同的可观察对象,已经构建了
shift$
可观察链,它引用了原始的
计时器
可观察对象

为了解决这个问题(假设您可以更新组件代码),您可以使用将
shift$
可观察值的创建推迟到订阅时,而不是组件实例化时:

shift$:Observable=defer(()=>this.now$.pipe(/){
const hour=now.getHours();
如果(小时<13){
提前返回;
}否则,如果(小时<20){
返回“晚”;
}否则{
返回“夜晚”;
}
})
));
在订阅
shift$
之前,传递给
defer
的工厂函数将不会执行。这样,
this.now$
在您订阅
shift$
之前将不会被引用,因此在订阅
shift$
之前,您将有机会在测试中重新定义
now$


展示这种方法。(打开控制台以验证测试中定义的日期是否为实际接收的日期。)

thx用于您的解决方案。奇怪的是,我认为这无关紧要,因为在创建时,我没有订户,而且两个都是冷的可观察对象。在您订阅它们之前,它们不会开始发出值,但可观察对象本身已经创建。如果你把它们仅仅看作物体,可能会更清楚
this.now$.pipe()
只返回一个对象(恰好是一个可观察对象),因此当您说
shift$=this.now$.pipe()
时,您将立即执行该
pipe()
方法并将其返回值分配给
shift$
。如果您随后将
now$
重新分配给其他对象,这不会影响
shift$
,因为
shift$
已经分配,它不会在订阅时重新执行
this.now$.pipe()
。是的,迈克。谢谢你的帮助:)
  it('should get late shift', (done) => {
    component.now$ = of(parseISO('2021-04-01T16:00:00Z'));
    component.shift$.subscribe((shift) => {
      expect(shift).toEqual('late');
      done();
    });
  });