
The Missing Ingredient for Angular Template Code Coverage and Future-Proof Testing

๐ง What's wrong with JIT?
โฐ Why now?

๐ Other Benefits of AOT Testing
โก๏ธ Faster Test Execution
๐ฏ Production-Symmetry
๐ฎ Future-Proof Tests
๐ค Drawbacks
๐ช Dynamic Component Constructs Should Be Avoided
// ๐ This is broken with AOT.
const fixture = render(`<app-button/>`, { imports: [Button] });
function render(template, { imports }) {
@Component({
template,
imports,
})
class TestContainer {}
return TestBed.createComponent(TestContainer);
}function render(template, { imports }) {
@Component({
jit: true,
template,
imports,
})
class TestContainer {}
return TestBed.createComponent(TestContainer);
}๐ฆฆ Shallow Testing is More Challenging
TestBed#overrideComponent
// app.cmp.spec.ts
vi.mock('./street-map.cmp', async () => {
return {
StreetMap: await import('./street-map-fake.cmp').then(
(m) => m.StreetMapFake
),
};
});
// street-map-fake.cmp.ts
@Component({
selector: 'app-street-map',
template: 'Fake Street Map',
})
class StreetMapFake implements StreetMap {
// ...
}TestBed#overrideComponent*.jit.spec.ts
๐จ๐ปโ๐ณ Taking Vitest with AOT for a Spin
1. Set up Vitest
2. Enable AOT
vite.config.js
export default defineConfig({
...
plugins: [
angular({ jit: false }),
...
],
...
});๐ Configure Code Coverage
istanbulv8istanbul
1. Install @vitest/coverage-istanbul
@vitest/coverage-istanbulnpm install -D @vitest/coverage-istanbul2. Choose istanbul as your coverage provider
istanbulvite.config.mts
export default defineConfig({
...
test: {
...
coverage: {
provider: 'istanbul',
},
},
});๐ฌ Watch it in Action
nx test my-app --coverage --ui --watch
# or
ng test --coverage --ui --watch


