question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Prefer declared component instead of same component on imported module

See original GitHub issue

Hi! First of all, thanks for your hard work simplificating my tests and I hope this becomes the de-facto library for Angular tests (as its name almost suggests it)✌

When we provide a service that’s already contained in one of the imorted modules, Angular Testing Library gives preference to the one on the providers array. 👍

import { MockProvider} from 'ng-mocks';

await render(ComponentToTest, {
      imports: [ModuleContainingServiceAbc],
      providers: [MockProvider(ServiceAbc)] // Succeeds to use this one
    });

I expected the same to happen on the declarations array, but this is not happening. Is this the implemented behavior? I’m not sure if I may be doing something wrong.

import { MockComponent } from 'ng-mocks';

await render(ComponentToTest, {
      imports: [ModuleContainingComponentAbc], 
      declarations: [MockComponent(ComponentAbc)] // Fails to use this one
    });

On my specific case, ComponentAbc is not directly declared and exported by ModuleContainingComponentAbc, but by another module that’s imported by ModuleContainingComponentAbc.

If you need details on how ng-mocks creates the mocks: https://ng-mocks.sudo.eu/api/MockProvider https://ng-mocks.sudo.eu/api/MockComponent

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
marcioggscommented, Mar 23, 2022

Hi. Sorry for the delay. The example below works using ngMocks.guts. Thanks @satanTime 👍

import { Component, NgModule } from '@angular/core';
import { render, screen } from '@testing-library/angular';
import { ngMocks } from 'ng-mocks';

@Component({
  selector: 'app-parent-component',
  template: '<app-child-component></app-child-component>',
})
class RealParentComponent {}

@Component({
  selector: 'app-child-component',
  template: '<p>Real child component</p>',
})
class RealChildComponent {}

@NgModule({
  declarations: [RealParentComponent, RealChildComponent],
})
export class RealModule {}

fdescribe('RealParentComponent', () => {
  it('Tests using Angular testing library', async () => {
    const dependencies = ngMocks.guts(null, RealModule, RealParentComponent);

    await render(RealParentComponent, dependencies);

    expect(screen.queryByText('Real child component')).toBeNull();
  });
});

@timdeschryver not being a fan of shallow rendering, what do you normally do instead? On my case the parent component has references to N child components, and these child components calls web-services on ngOnInit, so I wanted to avoid having to create mocks for each of these services. Thanks for the support!

1reaction
satanTimecommented, Mar 20, 2022

Hi @marcioggs,

in theory “exclude” option of ng-mocks should help you here:

const dependencies = ngMocks.guts(null, ModuleContainingServiceAbc, ComponentToTest);
await render(ComponentToTest, dependencies);

There is an article about spectator, however, the same should be true for angular-testing-library: https://ng-mocks.sudo.eu/extra/with-3rd-party.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Use component declared in app module in another module
first you have to add PopupNotificationComponent in declarations and export section of PopupNotificationModule like that
Read more >
TestBed to prefer components from the declarations array if ...
TestBed to prefer components from the declarations array if same component is already declared on an imported module #45362.
Read more >
Declaring Components in an Angular Module
We can list components, directives, and pipes, which are part of the module, in the "declarations" array. We can import other modules by...
Read more >
NgModule FAQ
Add declarable classes —components, directives, and pipes— to a declarations list. Declare these classes in exactly one module of the application.
Read more >
Avoiding common confusions with modules in Angular
It basically means that declarable types — components, directives and pipes — can only be used by components declared inside this module.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found