Adam Adamski
Adam Adamski

Reputation: 767

Testing simple angular component only with ngOnInit function

I'm a beginner when it comes to testing and I hope that you will explain me what is a good practice.

I have a simple service:

export class SessionService {
fetchFromStorage() {
    let x = localStorage.getItem('email');
    return JSON.parse(x);
}

saveInStorage(email) {
    localStorage.setItem('email', JSON.stringify(email));
}
}

and component which use that service:

export class LoginComponent implements OnInit, OnChanges {
email;

constructor(private service: SessionService) {
}

ngOnInit() {
    this.email = this.service.fetchFromStorage();
}

save() {
    this.service.saveInStorage(this.email);
}
}

I know that I should create localStorageMock ? And for example after calling saveInStorage() I have to check if that localStorageMock contains parameter that I passed to that function? I am not sure how to test fetchFromStorage, should I create in localStorageMock sth like this:

export class {
getItem(x){
if(x = 'email') return 'sth';
}
}

And third question what abou ngOnInit in my component? Isn't it to simple to write a test?

Upvotes: 2

Views: 332

Answers (1)

wprzechodzen
wprzechodzen

Reputation: 627

I think that it's worth to test if your component can succesfully fetch data from local storage and then if it can get it from there. I will use ng-test-runner library to make testing Angular components a little bit easier.

My components has template:

<button class="update-button" (click)="save()"> </button>
<input class="email-input" [(ngModel)]="email" />

and tests:

import {AppComponent} from "./app.component";
import {AppModule} from "./app.module";
import test, {App, click, expectThat, type} from "ng-test-runner";

describe('Local storage Component', () => {

  let app: App;
  let store = {};

  beforeAll(() => {
    spyOn(localStorage, 'getItem').and.callFake(function (key) {
      return store[key];
    });
    spyOn(localStorage, 'setItem').and.callFake(function (key, value) {
      return store[key] = value + '';
    });
    spyOn(localStorage, 'clear').and.callFake(function () {
      store = {};
    });
  });

  beforeEach(() => {
    app = test(AppModule);
  });

  afterEach(() => {
    localStorage.clear();
  });

  it('fetch email from local storage', () => {
    localStorage.setItem('email', 'emailFromLocalStorage');
    const comp = app.run(AppComponent);

    comp.verify(
      expectThat.textOf('.email').isEqualTo('emailFromLocalStorage')
    );
  });

  it('update email in local storage', () => {
    localStorage.setItem('email', 'emailFromLocalStorage');
    const comp = app.run(AppComponent);

    comp.perform(
      type('[email protected]').in('.email-input'),
      click.in('.update-button')
    );

    comp.verify(
      () => expect(localStorage.getItem('email')).toEqual('[email protected]')
    );
  });
});

I've created only spies for localStorage. If you will have more tests on localStorage, probably it will be better idea to extract it to some class - then you can just add it to your tests as a depedency.

Upvotes: 1

Related Questions