Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Karma-Test: Random Test fails when using async in other tests

I have a problem with Karma-Tests. When I run my tests, sometimes I have this error:

HeadlessChrome 70.0.3538 (Windows 10.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\n[object ErrorEvent] thrown",
    "str": "An error was thrown in afterAll\n[object ErrorEvent] thrown"
  }

If I do not change anything and run the same tests again, the test may not fail.

I've read that it could be a bug with asynchronous tests (https://github.com/karma-runner/karma/issues/2811#issuecomment-407600850), so I removed all my async and fakeasync tests. However, that still doesn't solve the problem. Without the async and fakeasync tests, I have this error:

HeadlessChrome 70.0.3538 (Windows 10.0.0) MyComponent should create FAILED
        [object ErrorEvent] thrown
HeadlessChrome 70.0.3538 (Windows 10.0.0): Executed 50 of 55 (1 FAILED) (0 secs / 0 secs)

But in the test of this Component i can't find an error:

describe('MyComponent', () => {
    let component: MyComponent;
    let fixture: ComponentFixture<MyComponent>;
    const zipService = jasmine.createSpyObj('ZipService', {
        search: of([])
    });

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [MyComponent, OnOffSwitchComponent, TranslatePipeMock],
            imports: [
                NgbModule.forRoot(),
                FormsModule,
                ReactiveFormsModule
            ],
            providers: [
                {provide: TranslateService, useValue: translateServiceMock()},
                {provide: UtilService, useValue: utilMock()},
                {provide: ZipService, useValue: zipService}
            ]
        }).compileComponents();
        fixture = TestBed.createComponent(MyComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();
    });

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

Does anyone have any idea what it could be about?

like image 669
flansemo Avatar asked Nov 08 '18 13:11

flansemo


1 Answers

your before each block is wrong, because you are attempting to create the component MyComponent before the compilation part finish, if you have a look into https://angular.io/api/core/testing/TestBed#compileComponents you can see that TestBed.compileComponents return a promise. so the boilerplate of you test should change sightly. First of all you need to make beforeEach aware that it's containing some async activities, there is more than one way of doing this including the native async/await, angular offer an utility async() out of the box. which is going to turn your test in beforeEach(async( () => {...})) then the second bit is that the creation of your mock should happen when the components are compiled. so all togheter your code is gonna look like

beforeEach(async(() => {
TestBed.configureTestingModule({
    declarations: [MyComponent, OnOffSwitchComponent, TranslatePipeMock],
    imports: [
        NgbModule.forRoot(),
        FormsModule,
        ReactiveFormsModule
    ],
    providers: [
        {provide: TranslateService, useValue: translateServiceMock()},
        {provide: UtilService, useValue: utilMock()},
        {provide: ZipService, useValue: zipService}
    ]
}).compileComponents().then(() => {
   fixture = TestBed.createComponent(MyComponent);
   component = fixture.componentInstance;
   fixture.detectChanges();
  });    
}));
like image 108
Valex Avatar answered Sep 27 '22 17:09

Valex