Testing that a component behaves correctly when a service it calls throws an exception using Angular 2

In my Angular 2 application, I try to execute the unit test the following component:

export class LoginComponent implements OnInit {
  invalidCredentials = false;
  unreachableBackend = false;

  constructor(private authService: AuthService) {}

  ngOnInit() {
    this.invalidCredentials = false;
  }

  onSubmit(user: any) {
    this.authService.authenticateUser(<User>user).subscribe((result) => {
      if (!result) {
        this.invalidCredentials = true;
      }
    }, (error) => {
      if (error instanceof InvalidCredentialsError) {
        this.invalidCredentials = true;
      } else {
        this.unreachableBackend = true;
      }
    });
  }
}

I have already successfully checked the happy path. Now, I would like to check that when authService.authenticateUser () throws an error message, invalidCredentials and unreachableBackend are set correctly. Here is what I am trying:

describe('Authentication triggering an error', () => {
  class FakeAuthService {
    authenticateUser(user: User) {
      throw new InvalidCredentialsError();
    }
  }

  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;
  let authService: AuthService;
  let spy: Spy;

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [LoginComponent],
      providers: [
        {provide: AuthService, useClass: FakeAuthService},
        {provide: TranslateService, useClass: FakeTranslateService}
      ],
      imports: [ FormsModule, TranslateModule, AlertModule ]
    });

    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
    authService = fixture.debugElement.injector.get(AuthService);
    spy = spyOn(authService, 'authenticateUser').and.callThrough();
  });

  it('should not log in successfully if authentication fails', () => {
    const user = {username: 'username', password: 'password'};
    component.onSubmit(user);

    expect(authService.authenticateUser).toHaveBeenCalledWith(user);
    expect(spy.calls.count()).toEqual(1, 'authenticateUser should have been called once');
    expect(component.invalidCredentials).toBe(true, 'credentials should be invalid because of the exception');
    expect(component.unreachableBackend).toBe(false, 'backend should be reachable at first');
  });
});

But when I run this test, I get the following crash:

PhantomJS 2.1.1 (Mac OS X 0.0.0). : . , , , . FAILED         [ Object], src/test.ts( 49782)         authenticateUser @webpack:///Users/sarbogast/dev/myproject/frontend/src/app/login/login.component.spec.ts: 112: 44 < - src/test.ts: 49782: 67         onSubmit @webpack:///Users/sarbogast/dev/myproject/frontend/src/app/login/login.component.ts: 9: 4896 < - src/test.ts: 85408: 5955         webpack:///Users/sarbogast/dev/myproject/frontend/src/app/login/login.component.spec.ts: 139: 25 < -src/test.ts: 49806: 31         invoke @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 203: 0 < - src/test.ts: 84251: 33         onInvoke @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/proxy.js: 72: 0 < - src/test.ts: 59204: 45         invoke @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 202: 0 < - src/test.ts: 84250: 42         run @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 96: 0 < - src/test.ts: 84144: 49         webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/jasmine-patch.js: 91: 27 < -src/test.ts: 58940: 53         execute @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/jasmine-patch.js: 119: 0 < -src/test.ts: 58968: 46         execute @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/jasmine-patch.js: 119: 0 < -src/test.ts: 58968: 46         invokeTask @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 236: 0 < - src/test.ts: 84284: 42         runTask @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 136: 0 < - src/test.ts: 84184: 57         drainMicroTaskQueue @webpack:///Users/sarbogast/dev/myproject/frontend/~/zone.js/dist/zone.js: 368: 0 < - src/test.ts: 84416: 42 PhantomJS 2.1.1 (Mac OS X 0.0.0): 33 38 (1 ) ( 5) (0,704 /0,842 )

, , - . , JS .

+4
1

, . , , , .

class FakeAuthService {
  authenticateUser(user: User) {
    // return this service so user can call subscribe
    return this;
  }

  subscribe(onNext, onError) {
    if (onError) {
      onError(new InvalidCredentialsError());
    }
  }
}

- Observable.throw(new InvalidCredentialsError())

authenticateUser(user: User) {
  return Observable.throw(new InvalidCredentialsError());
}

onError. , . , . . , .

. :

+2

Source: https://habr.com/ru/post/1658689/


All Articles