2

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?

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.