如何在不调用 fixture.detectChanges() 的情况下绑定模板?

Posted

技术标签:

【中文标题】如何在不调用 fixture.detectChanges() 的情况下绑定模板?【英文标题】:How can I bind the template without calling fixture.detectChanges()? 【发布时间】:2021-08-08 23:02:04 【问题描述】:

我正在为现有应用程序修复/添加单元测试。下面是代码遵循的模式。方法调用其他方法。单元测试使用一些模拟类。

调用 fixture.detectChanges() 就是调用 ngOnInit(),它会调用链中的所有其余方法。我只想调用一种方法,methodC()

我调用 fixture.detectChanges() 的原因是将新值绑定到模板。有没有办法在不调用 fixture.detectChanges() 的情况下这样做?

export class MyComponent implements OnInit 
  property1: any;
  property2: any

  constructor(
    private service1: Service1,
    private service2: Service2,
    )
   
  ngOnInit() 
    this.methodA();
  

  methodA()
    this.methodB();
  
  

  methodB()
     this.service1.doThis();
     this.service2.doThat()
         .subscribe(result => 
             this.property1 = result
             this.methodC()
      );
  

   methodC()
      //do something with PROPERTY1
      this.property2 = ...someValue;
   
 

这里是模板

 <div class="class1" *ngIf="property2?.value === 'someValue1'">
    Pending purchase 
 </div>
 <div class="class2" *ngIf="property2?.value === 'someValue2'">
    Order Submitted 
 </div>

我的单元测试

  it('should display pending purchase if amount is null or undefined', () => 
      fixture.detectChanges();    //--> THIS WILL RUN THE LIFECYCLE 
      
      component.property1 =     //SOME VALUE
      component.methodC().        //RUN THE LOGIC TO PRODUCE A VALUE FOR property2

      //fixture.detectChanges();  // THIS IS RUNNING EVERYTHING AND OVERRIDE NEW VALUES

      const elt = element.querySelector('.class1');
      expect(elt).not.toBeNull();
  );

感谢您的帮助。

【问题讨论】:

【参考方案1】:

覆盖应该可以解决问题:

it('should display pending purchase if amount is null or undefined', () => 
      const originalOnInitFunc = MyComponent.prototype.ngOnInit;
      const overrideOnInitFunc = () =>  ;
      MyComponent.prototype.ngOnInit = overrideOnInitFunc; // override ngOnInit

      component.property1 = ;
      component.methodC();

      fixture.detectChanges();

      const elt = element.querySelector('.class1');
      MyComponent.prototype.ngOnInit = originalOnInitFunc; // revert ngOnInit

      expect(elt).not.toBeNull();
   );

【讨论】:

我收到错误 MyComponent doesn't contain "prototype"。当我在ngOnInit() 中设置断点时,旧的实现仍在执行中。

以上是关于如何在不调用 fixture.detectChanges() 的情况下绑定模板?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不等待完成的情况下调用存储过程?

WCF反序列化如何在不调用构造函数的情况下实例化对象?

如何在不获取输出的情况下调用发送函数?

如何在不调用 textViewDidChangeSelection 的情况下设置 NSAttributedString 属性?

如何在不调用渲染函数的情况下访问 Context 的值? [复制]

Easymock:如何在不可见的情况下模拟受保护方法的调用