entan
entan

Reputation: 73

Angular 2 unit testing - multiple class instance

I am trying to set up unit test for simple Angular 2 app. I walk into trouble, beacuse unit tests creates multiple instances of class. See the code below

app.component.ts

import { TestClass } from './test.class';
import { Service } from './service';
import { Component } from '@angular/core';

@Component({
    selector: 'my-app',
    template: '<div></div>'
})
export class AppComponent {
    constructor(private s: Service) {
        let c = new TestClass();
    }
}

test.class.ts

export class TestClass {
    static counts = 0;

    constructor() {
        TestClass.counts++;
        if (TestClass.counts > 1)
            throw "Multiple TestClass instance";
    }
}

app.component.spec.ts

import { Service } from './service';
import { AppComponent } from './app.component';
import { TestBed, ComponentFixture } from '@angular/core/testing';

let fixture: ComponentFixture<AppComponent>;
describe('AppComponent', function () {
    beforeEach(() => {
        fixture = TestBed.configureTestingModule({
            declarations: [AppComponent],
            providers: [Service]
        }).createComponent(AppComponent);
    });

    afterEach(() => {
        fixture.destroy();
    });

    it('1', () => {
        expect(true).toBe(true);
    });

    it('2', () => {
        expect(true).toBe(true);
    });
});

The result of tests

[1]     Error: Error in ./AppComponent class AppComponent_Host - inline template
:0:0 caused by: Multiple TestClass instance

Is there a way to delete class instance before run next "it"?

Upvotes: 2

Views: 2950

Answers (1)

Kiran Yallabandi
Kiran Yallabandi

Reputation: 2584

The multiple instances of TestClass are being created because AppComponent is being created by TestBed once for every it block. In the above case that would be twice. afterEach runs once after every it block, There you can reset the static variable counts

describe('AppComponent', function () {
    beforeEach(() => {
        fixture = TestBed.configureTestingModule({
            declarations: [AppComponent],
            providers: [Service]
        }).createComponent(AppComponent);
    });

    afterEach(() => {
        fixture.destroy();
        TestClass.counts = 0
    });
......

This way you don't have to delete the TestClass it self to reset the counts variable

EDIT : Alternative method :

Since you are already destroying the component in the afterEach block, you can use ngOnDestroy life cycle hook on AppComponent to reset the count variable there it self. The logic here being that if the component itself is destroyed, Then so is the instance of TestClass. It has to be done this way as typescript does not have the concept of destructors

@Component({
    selector: 'my-app',
    template: '<div></div>'
})
export class AppComponent implements OnDestroy{
    constructor(private s: Service) {
        let c = new TestClass();
    }
    ngOnDestroy() {
       TestClass.counts = 0;
    }
}

Upvotes: 2

Related Questions