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

Attributes value of child component in unit tests disapear #15822

Closed
Shireilia opened this issue Apr 7, 2017 · 8 comments
Closed

Attributes value of child component in unit tests disapear #15822

Shireilia opened this issue Apr 7, 2017 · 8 comments
Labels
area: core Issues related to the framework runtime

Comments

@Shireilia
Copy link

Shireilia commented Apr 7, 2017

I'm submitting a ... (check one with "x")

[x ] bug report
[x ] feature request

Current behavior

I'm not sure if it's intended or not. If it is, this is a feature request :)

After migrating from 2.4.10 to 4.0.1, some of our unit tests broke. We are querying attributes of a child component, to check if we're giving the good values to it.

In version 2.4.10 and lower, we didn't need to compile the child component in order to get the attributes given to it (and could just compile the parent with the NO_ERRORS_SCHEMA to avoid errors), but now, in 4.0.1, if you don't declare the child component in TestBed, it's attributes will not be queryable and won't generate ng-reflects.

This is ONLY an issue in a test context, everything works fine in JiT and AoT.

Expected behavior
I'm expecting to be able to query the attributes of a child component without needing to compile it.

Minimal reproduction of the problem with instructions
I've asked a question in stack overflow for with just a basic sample in our real app conditions : http://stackoverflow.com/questions/43234464/angular-4-unit-tests-attributes-of-child-components
Also set up a repo with minimal repro based on mgechev angular seed :
https://github.com/Shireilia/Angular4TestRepro

In this repo, go to src/client/app/home/home.component.spec.ts and remove the sub component in the TestBed module (and add NO_ERRORS_SCHEMA) to see that the attributes of SubComponent disapear when launching npm run test.

What is the motivation / use case for changing the behavior?
When i'm unit testing a component that have child components, i may not care at all of the child behaviour and do not want to load it and compile it, but i would like to access the attributes in a clean way to test that i'm giving the correct values.

Now, i think that having to compile the subcomponents to access the attributes in the parent isn't necessarly wrong, but has limitations as follows :

Our applications is relying on our framework that is a module containing various components and services. What we're importing is the module, and when i got a component in my application that is using a framework component's as a child, i don't have access to the child component definition (it is not directly exposed and should not be IMO) in the tests (only the module where it's declared), meaning i can't declare it. I've tried to import the module, but it unfortunately does not work and breaks the tests.

Am i wrong or missing something, should we always compile the childs as well ? It sounds like a bit overkill to me :)

Please tell us about your environment:
Ubuntu 16.04, Visual Studio Code, Webpack (latest)

  • Angular version: 4.0.1

  • Browser: In test context, using chrome

  • Language: TypeScript 2.2.2

  • Node (for AoT issues): node --version = 7.7.X

@tbosch tbosch added the area: core Issues related to the framework runtime label Apr 8, 2017
@Shireilia
Copy link
Author

Hello guys,

Just checking to know if you have any news on this, if this is intended or not ? Thanks !

@tbosch
Copy link
Contributor

tbosch commented Apr 13, 2017

So you are talking about the ng-reflect-... attributes, right?

Yes, this is works as intended and was a bug in 2.x. We only create the ng-reflect attributes for @Input properties. We don't do this for native properties like <div [title]="..."> as these properties usually reflect their value as an attribute already (e.g. setting the property title will create an attribute title).

@tbosch tbosch closed this as completed Apr 13, 2017
@Shireilia
Copy link
Author

Shireilia commented Apr 14, 2017

Hello,

Thanks @tbosch for the answer. However, our problem here is about @Input given to components. If we are in a parent component and give the child component some values, like :

<div>
   <childcomponent [inputOne]="someValue">
   </childcomponent>
</div>

We won't be able to query the attribute inputOne NOR ng-reflect-input-one with TestBed IF we don't declare the subcomponent in the TestBed.

I would expect to be able to use NO_ERRORS_SCHEMA in order to query the attibutes without having to compile the subcomponent (it's a test context, i don't care about the child component behaviour, i just want to know if the parent is giving the correct value to it).

@Shireilia
Copy link
Author

Hello @tbosch, have you seen my answer about this ? :)

@Shireilia
Copy link
Author

Shireilia commented Apr 19, 2017

Finnally found a workaround for our problem but it's dirty (or i missed something, and would love to know what). I'll leave it here for anyone that might encounter the problem.

Problem recap :
Let's say you have a childComponent stored in a module. The said module is imported in a "Library" module, so the childComponent definition is NOT directly avalaible to the rest of the world.
Let's say you now have an app with a component that has the following template :

<div>
   <childcomponent [inputOne]="someValue">
   </childcomponent>
</div>

Now you want to make sure that childComponent is called with inputOne with someValue, but you don't care about what it should do, so you don't want to compile it. You then use the NO_ERRORS_SCHEMA in your TestBed.configureTestingModule call. You'll now see that the attribute [inputOne] IS NOT avalaible in the native element if you try to query it NOR the ng-reflect-input-one.

Workaround :
In this situation, you'll have to import the whole "Library" module as follow :

    TestBed.configureTestingModule({
      imports: [
        LibraryModule
      ],
      declarations: [
        ParentComponent
      ],
      providers: [...]
    });
    TestBed.compileComponents();

Rather than use the NO_ERROR_SCHEMA. Importing the whole library is IMO completly overkill, i should not have to import the whole library here.

@tbosch
Copy link
Contributor

tbosch commented Apr 26, 2017

In general, this is not a supported use case by Angular. I.e. if you don't include the child component to tell Angular that it should be compiled, then Angular does not do anything about that child component.

However, I think there is another issue behind this, see #16351

@Shireilia
Copy link
Author

Thank you so much for checking this again, that's the exact answer i was looking for :)

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: core Issues related to the framework runtime
Projects
None yet
Development

No branches or pull requests

2 participants