0

We're getting timeouts on random tests each time when CircleCI is running the tests (they all work fine locally). Usually we have to rerun the tests multiple times on CircleCI then they will eventually pass, but its starting to happen more and more and frankly becoming an annoyance.

The error given is:

Error: Timeout - Async function did not complete within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL)

This is an example of a test that fails (although its really random which one fails), and ive altered some of the names as i dont wish them to be shown

describe('SomeComponent', () => {
  // Mocks
  const serviceOne = jasmine.createSpyObj('ServiceOne', ['getFilterByType', 'createFilter']);
  const getFilterByTypeSpy = serviceOne.getFilterByType.and.returnValue(of({archived: false}));
  const createFilterSpy = serviceOne.createFilter.and.returnValue(of(new ()));
  const userService = {
    user$: of(new User()),
    remindersUpdated$: of(new User())
  };

  let component: SomeComponent;
  let fixture: ComponentFixture<SomeComponent>;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule,
        RouterTestingModule,
        ToastrModule.forRoot(),
        NgxPermissionsModule.forRoot(),
        NgxSmartModalModule.forRoot()
      ],
      declarations: [ SomeComponent ],
      providers: [
        DatePipe,
        {provide: ServiceOne, useValue: serviceOne},
        {provide: UserService, useValue: userService}
      ],
      schemas: [NO_ERRORS_SCHEMA]
    })
    .compileComponents()
    .then(() => {
      fixture = TestBed.createComponent(SomeComponent);
      component = fixture.componentInstance;
      getFilterByTypeSpy.calls.reset();
      fixture.detectChanges();
    });
  }));

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  describe('loading pre-existing filters',
    () => {
      it('should call getFilterByType on init', () => {
        expect(getFilterByTypeSpy).toHaveBeenCalledTimes(1);
      });

      it('should load in the filters into customFilter property', () => {
        expect(component.customFilter).toEqual({archived: false});
      });
    });

  describe('applying new filters',
    () => {
      beforeEach(() => {
        createFilterSpy.calls.reset();
        component.filtersApplied({archived: true});
      });

      it('should call createFilter', () => {
        expect(createFilterSpy).toHaveBeenCalledTimes(1);
      });

      it('customFilter should contain archived true', () => {
        expect(component.customFilter).toEqual({archived: true});
      });
    });
});

Is there something that i'm missing, or perhaps i'm setting the tests up incorrectly?

Thanks in advance

Spod
  • 1
  • 1
  • Some of the suggestions from here might help narrow it down https://stackoverflow.com/questions/22604644/jasmine-async-callback-was-not-invoked-within-timeout-specified-by-jasmine-defa – Drenai Feb 20 '22 at 00:07

1 Answers1

0

The most obvious thing that is wrong is that you are sharing your service mock instances across all tests - they are created once only in the top level describe then assigned to each test in the beforeEach.

This could certainly contribute to random test failures (assuming your CI is setup to run tests in parallel and your local is not).

Try this to ensure that each test gets new service mock instances:

let serviceOne, getFilterByTypeSpy, userService;

beforeEach(waitForAsync(() => {
  serviceOne = jasmine.createSpyObj('ServiceOne', ['getFilterByType', 'createFilter']);
  getFilterByTypeSpy = serviceOne.getFilterByType.and.returnValue(of({archived: false}));
  createFilterSpy = serviceOne.createFilter.and.returnValue(of(new ()));
  userService = {
    user$: of(new User()),
    remindersUpdated$: of(new User())
  };

  TestBed.configureTestingModule({
  ...

wlf
  • 3,086
  • 1
  • 19
  • 29
  • All of those mocks use synchronous observables, e.g there's no `timer` or `delay`, so if global mocks was an issue I'd expect the tests to fail, but wouldn't expect `timeout` errors – Drenai Feb 20 '22 at 06:47
  • I agree, but it in the absence of anything else obvious it would be a good place to start with some outside chance it would have an impact on the timeouts. – wlf Feb 20 '22 at 07:49