puddlejumper26 / blogs

Personal Tech Blogs
4 stars 1 forks source link

Testing Services in Angular #15

Open puddlejumper26 opened 4 years ago

puddlejumper26 commented 4 years ago

For the serviceSpy please check this blog

Service in the Component

Services are often the easiest files to unit test.

Testing with Observable and Promise needs done( ).

//   ====> Straight Jasmine testing without Angular's testing support
describe('ValueService', () => {
  let service: ValueService;                            // ==========> service: ValueService
  beforeEach(() => { service = new ValueService(); });

  it('#getValue should return real value', () => {
    expect(service.getValue()).toBe('real value');
  });

  it('#getObservableValue should return value from observable',   // =====> Observable
    (done: DoneFn) => {
    service.getObservableValue().subscribe(value => {
      expect(value).toBe('observable value');
      done();
    });
  });

  it('#getPromiseValue should return value from a promise',       // ========> Promise
    (done: DoneFn) => { 
    service.getPromiseValue().then(value => {
      expect(value).toBe('promise value');
      done();
    });
  });
});

Testing services with the TestBed

TheTestBed creates a dynamically-constructed Angular test module that emulates an Angular @NgModule.

The TestBed.configureTestingModule() method takes a metadata object that can have most of the properties of an @NgModule.

let service: ValueService;

beforeEach(() => {
  TestBed.configureTestingModule({ providers: [ValueService] });
});

Then inject it inside a test by calling TestBed.get() with the service class as the argument.

it('should use ValueService', () => {
  service = TestBed.get(ValueService);
  expect(service.getValue()).toBe('real value');
});

When testing a service with a dependency, provide the mock in the providers array.

let masterService: MasterService;
let valueServiceSpy: jasmine.SpyObj<ValueService>;

beforeEach(() => {
  const spy = jasmine.createSpyObj('ValueService', ['getValue']);

  TestBed.configureTestingModule({
    // Provide both the service-to-test and its (spy) dependency
    providers: [
      MasterService,
      { provide: ValueService, useValue: spy }
    ]
  });
  // Inject both the service-to-test and its (spy) dependency
  masterService = TestBed.get(MasterService);
  valueServiceSpy = TestBed.get(ValueService);
});
it('#getValue should return stubbed value from a spy', () => {
  const stubValue = 'stub value';
  valueServiceSpy.getValue.and.returnValue(stubValue);

  expect(masterService.getValue())
    .toBe(stubValue, 'service returned stub value');
  expect(valueServiceSpy.getValue.calls.count())
    .toBe(1, 'spy method was called once');
  expect(valueServiceSpy.getValue.calls.mostRecent().returnValue)
    .toBe(stubValue);
});