3

I'm trying to test the following service.

@Injectable()
export class TranslationService {

  language = 'NL';

  constructor(contextService: ContextService) {
    let context = contextService.getContext();
    this.language = context.language;
  }
}

The actual test:

describe('TranslationService', () => {

  let service: TranslationService;
  let contextServiceSpy: jasmine.SpyObj<ContextService>;

  beforeEach(() => {

    const contextSpy = jasmine.createSpyObj('ContextService', ['getContext']);
 
    TestBed.configureTestingModule({
      providers: [
        TranslationService,
        {provide: ContextService, useValue: contextSpy}]
    });

    service = TestBed.get(TranslationService);
    contextServiceSpy = TestBed.get(ContextService);
  
  });

  it('should create an instance', () => {

    const context: Context = {
      language: 'EN'
    };

    contextServiceSpy.getContext.and.returnValue(context);

    expect(service).toBeDefined();
    expect(contextServiceSpy.getContext.calls.count()).toBe(1, 'spy method was called once');
    expect(contextServiceSpy.getContext.calls.mostRecent().returnValue).toBe(context);
  });

});

Now when running my test it returns with an error:

TypeError: Cannot read property 'language' of undefined

This means that spy did not return my mocked context. But I don't have a clue why it isn't. Anyone?

I used https://angular.io/guide/testing#service-tests

angular 5.2.4

jasmine 2.8.0

Stefan
  • 832
  • 8
  • 10

1 Answers1

3

Service constructor is called before mocking getContext stub.

It should be:

contextServiceSpy = TestBed.get(ContextService);
contextServiceSpy.getContext.and.returnValue(context);
service = TestBed.get(TranslationService);
Estus Flask
  • 206,104
  • 70
  • 425
  • 565
  • 1
    Pff.... thanks a lot! Now it is working as expected. From the documentation (https://angular.io/guide/testing#service-tests) it is not clear and it seems they are calling '....and.returnValue(..)' also after: masterService = TestBed.get(MasterService); valueServiceSpy = TestBed.get(ValueService); – Stefan Mar 01 '18 at 10:29
  • You are welcome. This can be done in the docs this way because mocked method isn't called on service class construction. – Estus Flask Mar 01 '18 at 10:41
  • ah ok! Clear! Thanks a lot. – Stefan Mar 01 '18 at 10:50