6
votes

I have a problem with Angular4 unit tests by karma/jasmine. I run tests on PhantomJS browser locally and everything's fine. But when I try run the same tests on jenkins (on PhantomJS) i got error:

Stacktrace

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

EVERY test from login-form.component.spec.ts throws the same error

login-from.component.spec.ts

describe('LoginFormComponent', () => {
  let fixture;
  let submitBtn: DebugElement;
  let component;
  let authenticationService: AuthenticationService = null;
  let backend: MockBackend = null;
  const requestData = {
    //mock request data
  };
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        LoginFormComponent,
      ],
      imports: [
        CommonModule,
        FormsModule,
        FormElementsModule,
        ReactiveFormsModule,
        RouterTestingModule,
        TranslateModule,
        SharedModule,
        EwniosekSharedModule,
        Ng2PageScrollModule,
        ModalModule.forRoot(),
        VexModalModule,
      ],
      providers: [
        i18nService,
        AuthenticationService,
        BaseRequestOptions,
        {provide: XHRBackend, useExisting: MockBackend},
        {
          provide: HttpService,
          useFactory: (backendInstance: XHRBackend, defaultOptions: BaseRequestOptions) => {
            return new HttpService(backendInstance, defaultOptions);
          },
          deps: [MockBackend, BaseRequestOptions]
        },
        MockBackend
      ],
    }).compileComponents();
    fixture = TestBed.createComponent(LoginFormComponent);
    authenticationService = TestBed.get(AuthenticationService);
    backend = TestBed.get(MockBackend);
    component = fixture.debugElement.componentInstance;
    submitBtn = fixture.debugElement.query(By.css('#submitBtn'));
  }));

  it('should create this component', () => {
    expect(component).toBeTruthy();
  });
  it('should have sumbit button', () => {
    expect(submitBtn).not.toBeNull();
  });
  it('should be avaible on /xxx/login url', () => {
    backend.connections.subscribe((connection: MockConnection) => {
      const options = new ResponseOptions({
        body: JSON.stringify(requestData)
      });
      connection.mockRespond(new Response(options));
      expect(connection.request.url).toEqual('/xxx/login');
    });
  });
  it('should click to submit button to login', () => {
    spyOn<any>(component, 'onSubmit');
    expect(fixture.debugElement.query(By.css('#submitBtn'))).toBeDefined();
    submitBtn.nativeElement.click();
    fixture.detectChanges();
    expect(component.onSubmit).toHaveBeenCalled();
  });
  it('should call login method by URL', (done) => {
    backend.connections.subscribe((connection: MockConnection) => {
      const options = new ResponseOptions({
        body: JSON.stringify(requestData)
      });
      connection.mockRespond(new Response(options));
      expect(connection.request.url).toEqual('/xxx/login');
    });
    authenticationService.login('TEST', 'xxx').subscribe(
      (res) => {
        expect(res.username).toContain('TEST');
        expect(res.password).toContain('xxx');
        expect(res.sex).toContain('male');
        done();
      }
    )
  });
});

Anyone can tell me why I got this error for every test in this component?

2

2 Answers

16
votes

you should remove async beforeEach(async(() => {

2
votes

All your services need to be mocked you can't just simple define them and hope jenkins make an api call. Cause jenkins not work Async and will give a timeout.

i18nService,
AuthenticationService,

These services need to be mocked to, with mockdata.