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.
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()orafterAll()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.configureTestingModuleto be created async()? Your test will run but the async part will probably never get called before theit(..Hope these ideas will help :)