9

My component file has the following code

@ViewChild('clusterCard', { static: false }) clusterCard: ElementRef;



highLightTheClusterCard(point: PickupClusterPoint) {
    if (point) {
      const card: HTMLElement = _get(this.clusterCard, 'nativeElement');
      const selectedPoint: PositioningPoint = this.lane.data.selectedPostioningPoint;

      /* if card is available, position point of the card and the cluster is same and infowindow over the cluster is open then
         highlight the card */
      if (card && _isEqual(point.pointData, selectedPoint) && point.openInfoWindow) {
        card.scrollIntoView();
        card['style'].borderLeft = `5px solid ${this.lane.data.color || 'transparent'}`;
      } else {
        card['style'].borderLeft = `5px solid transparent`;
      }
    }
  }

  ngAfterViewChecked(): void {
    ...some code

    this.pickupClusterPointsService.positioningPoint$
      .pipe(skip(1), takeUntil(this.unsubscriber.done))
      .subscribe((point: PickupClusterPoint) => {
        this.highLightTheClusterCard(point);
      });
  }

HTML file

    <div #clusterCard>
      <pickup-cluster-stop-card
       ..some code
      >
      </pickup-cluster-stop-card>
    </div>

I want to unit test the highLightTheClusterCard method. I am getting

TypeError: Cannot read property 'pipe' of undefined error properties

and TypeError: Cannot set property 'borderLeft' of undefined at

Unit test file

  beforeEach(() => {
   
     ...some code

    fixture = TestBed.createComponent(RouteLaneComponent);
    component = fixture.componentInstance;

    ....some code

    fixture.detectChanges();
  });

  fdescribe('highLightTheClusterCard', () => {
     it('should expect cluster card to be defined ', () => {
        // component.clusterCard.nativeElement = new HTMLElement();
        component.clusterCard = new ElementRef({ nativeElement: jasmine.createSpyObj('nativeElement', ['scrollIntoView', 'style'])});
        component.highLightTheClusterCard({ pointData: new PositioningPoint(), openInfoWindow: true} as PickupClusterPoint);
        // expect(component.clusterCard).toBeDefined();
         // expect(component.clusterCard.nativeElement.scrollIntoView).toHaveBeenCalled();
     });
  });

I read this How to mock a nativeElement.focus() in Angular 4 spec file

but still, I am unable to make it green.

  MockService(PickupClusterPointsService, {
          ...more code
          positioningPoint$: of(undefined),
        }),  

Solution: I have added positioningPoint$: of(undefined) in mock service. MockService is inside the Provider. you can see above lines.

describe('highLightTheClusterCard', () => {
        it('should expect cluster card to be highlighted when hover over infowindow ', () => {
            component.lane.data.selectedPostioningPoint = new PositioningPoint();
            component.lane.data.color = '#2196F3';
            component.clusterCard = {
              nativeElement: jasmine.createSpyObj('nativeElement', ['scrollIntoView', 'style'])
            };
    
           component.highLightTheClusterCard({ pointData: new PositioningPoint(), openInfoWindow: true} as PickupClusterPoint);
    
           expect(component.clusterCard).toBeDefined();
           expect(component.clusterCard.nativeElement.scrollIntoView).toHaveBeenCalled();
           expect(component.clusterCard.nativeElement.style.borderLeft).toBe('5px solid #2196F3');
        });
        it('should expect cluster card not to be highlighted when hover out from the infowindow', () => {
          component.lane.data.selectedPostioningPoint = new PositioningPoint();
          component.clusterCard = {
            nativeElement: jasmine.createSpyObj('nativeElement', ['scrollIntoView', 'style'])
          };
         component.highLightTheClusterCard({ pointData: new PositioningPoint(), openInfoWindow: false} as PickupClusterPoint);
    
         expect(component.clusterCard).toBeDefined();
         expect(component.clusterCard.nativeElement.style.borderLeft).toBe('5px solid transparent');
      });
     });
sunil
  • 660
  • 8
  • 20

2 Answers2

2

You have several issues it seems.

Your first error

TypeError: Cannot read property 'pipe' of undefined error properties

come from that you haven't instantiated your pickupClusterPointsService service properly.

The second error

TypeError: Cannot set property 'borderLeft' of undefined at

I'm not sure just yet

Lucho
  • 1,455
  • 1
  • 13
  • 25
  • Yes, you are right. I got it. will update my code. – sunil Nov 28 '20 at 21:51
  • I need some help to unit test this https://pastebin.pl/view/08e0f7ca – sunil Dec 11 '20 at 13:54
  • Hi, if you create a new post with this code in a [stackblitz](https://www.stackblitz.com) and pm me i can take a look at it. – Lucho Dec 11 '20 at 17:46
  • Hi Lucho I can not create it at stackblitz. It is a part of application and application is huge. But if you look at the code it is almost the same as the above code in the current question. card is HTMLElement element. In the new code, I do not want to apply a border to the card (card is div). I want to apply the border to the angular component which is within the div. – sunil Dec 11 '20 at 19:23
  • I am using this line pickupClusterCard = card.querySelector('.pnd-BaseStopCard'); to get the angular component ( – sunil Dec 11 '20 at 19:23
  • Again you have to write a new separate post with your new questions. You don't have to include your whole app, just include the isolated issue in the stackblitz – Lucho Dec 11 '20 at 21:30
0

You have created your spy with "style" as a function of native element

jasmine.createSpyObj('nativeElement', ['scrollIntoView', 'style'])

instead of property

jasmine.createSpyObj('nativeElement', ['scrollIntoView'], {style: {}})

Therefore TypeError: Cannot set property 'borderLeft' of undefined is because in card['style'].borderLeft, card['style'] doesn't exist. instead, try it like this:

component.clusterCard = { nativeElement: jasmine.createSpyObj('nativeElement', ['scrollIntoView'], {style: jasmine.createSpyObj('style', [], {borderLeft: 'some string value'})})};
bokkie
  • 1,477
  • 4
  • 21
  • 40