Jeremy
Jeremy

Reputation: 1288

Angular Testing, are there better ways to write this code?

I'm learning Angular testing, but can't seem to find any good resources on if I'm doing this the proper way.

In my spec file, I am running a function setDashboardGreeting(hours) but this does the same thing as the function as I already have in my component: getTime(). Is there a way I can use the same function so I don't have to re-write it in my test?

describe('TestComponent', () => {
  let component: TestComponent;
  let dashboardGreeting;
  let hours;
  function setDashboardGreeting() {
    if (hours < 5) component.dashboardGreeting = 'Morning';
    else if (hours < 10) component.dashboardGreeting = 'Afternoon';
    else component.dashboardGreeting = 'Evening';
  }

  beforeEach(() => {
    dashboardGreeting = '';
    component = new TestComponent();
  });

  describe('DashboardGreeting', () => {
    it('should return Morning', () => {
      let hours = 10
      setDashboardGreeting();

      expect(component.dashboardGreeting).toBe('Good Morning');
    });
  });
});

And then in my component, I have this function:


getTime() {
  const now = new Date();
  const hours = now.getHours();

  if (hours < 5) this.dashboardGreeting = 'Morning';
  else if (hours < 10) this.dashboardGreeting = 'Afternoon';
  else this.dashboardGreeting = 'Evening';
}

Do I need to re-write the if/else statement in my test or if this possible to use the getTime() function from my component?

Upvotes: 2

Views: 47

Answers (1)

benbotto
benbotto

Reputation: 2440

One way to simplify the testing and reduce repetition would be to make it so that the date (now in your code) can be passed in by the unit tests. For example:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
  salutation = '';

  ngOnInit(): void {
    this.salutation = this.getSalutation(new Date());
  }

  getSalutation(date: Date): string {
    const hours = date.getHours();

    if (hours < 5)
      return 'Good Morning';
    else if (hours < 10)
      return 'Good Afternoon';
    else
      return 'Good Evening';
  }
}

Note that I renamed getDate to getSalutation. I also made it return a value (get) rather than set a value.

From your tests you can then call getSalutation with a variety of dates to check that the salutations are as expected. You can also check that salutation is set when ngOnInit is called, and that ngOnInit calls getSalutation with a Date instance using a spy.

Upvotes: 1

Related Questions