Unit test fails after adding a new test

237 Views Asked by At

I am currently working on an Ionic (v3) app and we have several tests to test services, pages and components.

Everything was working fine until I added a new test for a component.

Both tests run fine individually (if started with fdescribe, or if I comment one of them out).

The tests look like this:

verify-key.spec.ts

describe('Component: VerifyKey', () => {

  let component: VerifyKeyComponent
  let fixture: ComponentFixture<VerifyKeyComponent>

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [VerifyKeyComponent],
      imports: [
        IonicModule.forRoot(VerifyKeyComponent)
      ]
    })

    // create component and test fixture
    fixture = TestBed.createComponent(VerifyKeyComponent)

    // get test component from the fixture
    component = fixture.componentInstance
  })
  ...
})

wallet-select-coins.spec.ts

describe('Wallet-Select-Coin Component', () => {

  let fixture: ComponentFixture<WalletSelectCoinsPage>
  let component: WalletSelectCoinsPage

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [WalletSelectCoinsPage],
      imports: [
        IonicModule.forRoot(WalletSelectCoinsPage),
        ComponentsModule,
        IonicStorageModule.forRoot({
          name: '__airgap_storage',
          driverOrder: ['localstorage']
        })
      ],
      providers: [
        SecretsProvider,
        {
          provide: SecureStorageService,
          useFactory: SecureStorageFactory,
          deps: [Platform]
        },
        { provide: NavController, useClass: NavControllerMock },
        { provide: NavParams, useClass: NavParamsMock },
        { provide: StatusBar, useClass: StatusBarMock },
        { provide: SplashScreen, useClass: SplashScreenMock },
        { provide: Platform, useClass: PlatformMock }
      ]
    })
  }))

  beforeEach(() => {
    fixture = TestBed.createComponent(WalletSelectCoinsPage)
    component = fixture.componentInstance
    fixture.detectChanges()
  })

  it('should not show hd-wallet dropdown if currency does not support it', () => {
    let el = fixture.debugElement.nativeElement
    let ethereumRadio = el.querySelector('#eth')

    // click on ethereum
    ethereumRadio.click()
    fixture.detectChanges()
    console.log(component.selectedProtocol)
    expect(component.selectedProtocol).toBeDefined() // This fails
    expect(component.selectedProtocol.identifier).toEqual('eth')

    // eth should not show hd wallets
    let hdWalletSelector = el.querySelector('#wallet-type-selector')
    expect(hdWalletSelector).toBeFalsy()
  })

})

If both tests are enabled, the second one fails at the line expect(component.selectedProtocol).toBeDefined() with the error Expected undefined to be defined.

If I comment out the line fixture = TestBed.createComponent(VerifyKeyComponent) from the first file, then the second test runs without any issues.

My first idea was that the TestBed somehow gets modified in the first test. So I tried adding TestBed.resetTestingModule() after the first test, but that didn't change anything.

Any help would be greatly appreciated.

1

There are 1 best solutions below

2
Mattstir On

When writing tests its best practice to clean up everything after every test so that all test can run in random order without effecting any other test.

I would suggest to introduce a afterEach() or afterAll() in every test which clears any data which is produced. Because most test environments run all tests in the same context.

And why would you like that your TestBed.configureTestingModule to be created async()? Your test will run but the async part will probably never get called before the it(..

Hope these ideas will help :)