We use the testing library and MockBuilder
from ng-mocks to write unit tests for angular components:
...
<ng-container *ngTemplateOutlet="previewContent" />
...
<!-- Preview Content -->
<ng-template #previewContent>
<p data-testid="test-text">template is here :)</p>
</ng-template>
and in the component.spec.ts:
function setupBuilder() {
return MockBuilder(SomeComponent);
}
async function setup(inputs: {
// inputs...
}) {
const builder = setupBuilder();
const utils = await render(SomeComponent, {
...builder.build(),
inputs,
});
const user = userEvent.setup();
utils.debug();
return { ...utils, user, component: utils.fixture.componentInstance };
}
describe('SomeComponent', () => {
it('should render', async () => {
const { component } = await setup({ ... });
expect(component).toBeDefined();
expect(screen.getByTestId('test-text')).toBeInTheDocument();
});
However, this fails, and the debug logging shows that the template is not included in the rendered DOM.
Finally I found the reason and the solution: MockBuilder automatically mocks all things that the component uses, including the NgTemplateOutlet
directive... So when I modify my setupBuilder
to keep this, it works as expected:
function setupBuilder() {
return MockBuilder(SomeComponent)
.keep(NgTemplateOutlet); // <== important if I want the directive to work
}