How can I bind the template without calling fixture.detectChanges()?

100 Views Asked by At

I am fixing/adding unit tests to an existing application. Below is the patterns that the code follows. Methods call other methods. Unit tests use some mock classes.

Calling fixture.detectChanges() is calling ngOnInit(), which calls all the rest of the methods in chain. All I want is to call one method, methodC().

The reason I am calling fixture.detectChanges() is to bind new values to the template. Is there a way to do so without calling 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;
   }
 }

Here the template

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

My unit test

  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();
  });

Thanks for helping.

1

There are 1 best solutions below

1
On

Override should do the trick:

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();
   });