getsaf / shallow-render

Angular testing made easy with shallow rendering and easy mocking. https://getsaf.github.io/shallow-render
MIT License
273 stars 25 forks source link

Tried to bind to a property that is not marked as @Input: vm from base class #217

Closed rodrigofante closed 1 year ago

rodrigofante commented 2 years ago

I have an abstract base class that includes an @input property, when I extend that base class I use that input in many places in the extended class.

The issue I'm having is that, when testing it on binding that property I get the following error: Error: Tried to bind to a property that is not marked as @Input: vm

Here's an example on what would be the scenario:

export abstract class BaseClass{
   @Input() public vm: MyProperty;
}

export class MyComponent extends BaseClass{
  //code here
}

now, if I try to initialise my test in the following way:

beforeEach(async () => {
  shallow = new Shallow(MyComponent, MyModule);
  const { instance } = await shallow.declare().render({ bind: { vm: myMockValue } });
});

this will break when I run it as it won't identify the vm property as an input, which is, but it's declared in the base class, not in the child class (the one I'm testing).

Is this a bug or am I supposed to test in a different way when the @input is declared in the base class?

Ishou commented 2 years ago

I can confirm this is a bug that appeared with the Angular 13 compatibility update, the same code was working correctly before.

Ishou commented 2 years ago

Here is a workaround I just found:

export class MyComponent extends BaseClass {
  @Input() public override vm: MyProperty;
}
antch commented 2 years ago

Also running into this -- thank you for the workaround but it unfortunately adds a ton of boilerplate. In the case of overriding a setter it gets especially verbose. Hopefully this is just a regression that can be resolved...

getsaf commented 2 years ago

Sorry for the delays, I cannot reproduce this issue, see #220.

Could you provide a reproduction?

antch commented 2 years ago

I was able to get your test to fail by adding either an @Input or @Output to the sub-class, for example:

@Component({
    'selector': 'my-component'
})
class MyComponent extends BaseClass {
    @Input() label = 'foo';
}

Error:

Error: Tried to bind to a property that is not marked as @Input: enabled
Available input bindings: label
antch commented 2 years ago

I'm wondering as to why this was closed, it seems like a valid issue?

getsaf commented 2 years ago

Sorry about that, was unintentional. I can try looking into this later today.

JoeBeer commented 2 years ago

@getsaf What is the status of this issue?

johnwest80 commented 1 year ago

@getsaf hey there, me again. looks like we're hitting this one, too. can't do much, but i'll owe you a cup of coffee for helping with these issues :). thx.

getsaf commented 1 year ago

Hey @johnwest80 hope all is well. The I/O detection I had in place was not taking inheritance into account properly. Should be fixed in v14.2.1.

Again, sorry for the delays on this, I don't get to do much Angular work lately. I do plan on updating this to NG 15 soon too unless someone in the community wants to give it a go.

antch commented 1 year ago

Thank you for addressing this -- is there any hope of the fix being back-ported into 13.x as that's where it started occurring?

getsaf commented 1 year ago

I will have some time off for the holidays soon. I think it'll be easy to backport.

getsaf commented 1 year ago

@antch I just backported this to 13.0.2!