Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mocked component and host decorator #10

Closed
kenjiqq opened this issue May 29, 2018 · 7 comments
Closed

Mocked component and host decorator #10

kenjiqq opened this issue May 29, 2018 · 7 comments

Comments

@kenjiqq
Copy link
Contributor

kenjiqq commented May 29, 2018

If you have 2 nested components like this

<outer>
  <inner></inner>
</outer>

And the inner component uses a host decorator to inject the outer component in it's constructor
constructor( @Host() public outer: OuterComponent ) { }

When you want to test the inner component it does not seem like it's possible to mock outer component in the tests as the component declared in the TestBed MockComponent(OuterComponent) is not found and injected into the constructor of the inner component.

Is there any way to make this work?

@ike18t
Copy link
Collaborator

ike18t commented May 29, 2018

Here's an example I whipped up really quick:

https://stackblitz.com/edit/bah?embed=1&file=app/hello.component.spec.ts

The meat of it is:

      providers: [ 
        { 
          provide: AppComponent, 
          useClass: MockComponent(AppComponent)
        } 
      ]

@kenjiqq
Copy link
Contributor Author

kenjiqq commented May 29, 2018

I didn't know you could provide components, that's cool. But i modified your code to be closer to mine and it still didn't work.
The main difference is my "hello" component is projected content. So i move it in the tests and made a testComponent in the spec file.

@Component({ template: `
    <my-app>
        <hello>
        </hello>
    </my-app>
` })
class TestComponent {}

It seems like it might be when projection is involved that the problem arises?

Here is the modified one, i added a new spec file as well that is identical except is just removed MockComponent and those tests work.
https://stackblitz.com/edit/bah-imogy4?embed=1&file=app/hello.component.spec.ts

@getsaf
Copy link
Collaborator

getsaf commented May 29, 2018

@kenborge looks like the issue here is related to the TestComponent approach combined with injection of a mock parent. I'm not sure why TestBed doesn't care for the approach. I would recommend avoiding the TestComponent "layer" in this case and stick to just TestBed.createComponent(HelloComponent). It'll give you more control over your component inputs too so it's kind-of a double-win.

@ike18t showed that you can provide components in the providers block, you may also try using TestBed.overrideComponent to do this too. Not sure if there is a way to get TestBed to play nice with this approach, but it's worth mentioning. I must say though, @ike18t's suggestion seems to be much more readable and pragmatic than this using overrideComponent.

    TestBed.configureTestingModule({
      declarations: [ HelloComponent ],
    });
    TestBed.overrideComponent(HelloComponent, {
      set: {
        viewProviders: [
          {provide: AppComponent, useClass: MockComponent(AppComponent)}
        ]
      }
    });

I got that test running in this StackBlitz project, it's very similar to the one @ike18t provided, just using the different injection technique.

@kenjiqq
Copy link
Contributor Author

kenjiqq commented May 30, 2018

@getsaf Creating a TestComponent does have some pretty valid use cases. Like if you want to test projected content. So you need to compile something like:

@Component({ template: `
    <hello>
      PROJECTED CONTENT
    </hello>
` })
class TestComponent {}

It does seem like this is possible with the viewProviders approach though. It doesn't work using normal provide like @ike18t mentioned, but overriding viewProviders seems to be a solution.
https://stackblitz.com/edit/bah-yfg6d8?embed=1&file=app/hello.component.spec.ts

@ike18t
Copy link
Collaborator

ike18t commented May 31, 2018

@kenborge Did that solve your problem? Is it cool if I close this issue?

@ike18t
Copy link
Collaborator

ike18t commented Jun 4, 2018

Closing unless there is a reason not to. Feel free to reopen if this is still an issue.

@ike18t ike18t closed this as completed Jun 4, 2018
@kenjiqq
Copy link
Contributor Author

kenjiqq commented Jun 16, 2018

@ike18t yeah it did work using the viewProviders approach. I would still consider it a bug though or at least a limitation of the mock framework that maybe should be documented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants