Closed Blafasel3 closed 7 months ago
@kfrancois can you check please?
Interesting - I just set up a case where this does seem to function properly and ngOnChanges
does fire when calling .setInput
. If you can provide a reproduction example (some repo or StackBlitz) I'd be happy to take a look and fix!
As of Spectator 17, ngOnChanges
does not get called by Spectator anymore. Previously, Spectator would explicitly call a component's ngOnChanges
with a "mocked" SimpleChanges
object.
Now, this ngOnChanges
call happens by TestBed/Angular itself.
Example repo: https://github.com/Blafasel3/spectator-issue
The behavior has to do with change detection strategy of the component. If its the default, the test succeeds. If it's onPush
, the test fails on the expected HTMLButtonElement#disabled
in Line 23:
I was happy to actually find the time to reproduce this, but I could not dive much further. Hope this helps. Same test succeeds with spectator v16 with both change detection strategies.
Edit: I confirmed this on our application code. Every test that fails succeeds if I change the changeDetectionStrategy from onPush
to Default
.
Update: Manually calling spectator.detectComponentChanges(); fixes the issue.
spectator.setInput({ disableButton: false })
spectator.detectComponentChanges();
Tried it in our code, looks good. Issue closed. Thanks for the quick fix & release!
Thank you for verifying @Blafasel3! 🙌
Is this a regression?
Yes
Description
I upgraded our Angular 16 App to Angular 17 (including Angular Material) and everything worked smoothly. In unit testing, we rely heavily on Spectator. After the update from spectator 16.0.0 to 17.0.0 (as a granular update) tests started to fail at random.
What I found out so far ist that
spectator.setInput(..)
actually updates the values on the component but does not seem to update the UI correctly. When creating the component, the state is set correctly, but e.g. button texts which should change via the logic triggered bysetInput
never get updated after initilization. E.g. we are doing this in our test:The button in the example is a
mat-menu-item
. In Spectator v16 this worked fine and the button is enabled and has the correct text as expected after calling setInput. In Spectator v17 the component attributes derived fromsetInput
are still correct, but the button in the above example is still disabled and has the incorrect text (which is derived from the initial state set increateComponent
. Also, in v17,Component#ngOnChanges
is not called anymore but the attributes are set "hard" in https://github.com/ngneat/spectator/pull/638/files#diff-4b8aa7924b03115ef01b9f128e7c8886004c8e5bdd2768445cdf3a9be00c81fa and https://github.com/ngneat/spectator/pull/638/files#diff-582dd3e11b71bddafaec5400161349f59f51a76da92412359207423fa782c216R29-R42 If I'd have to guess, the changes to thesetProps
seem to miss out on something that happend in the previous code rather implicitly.Please provide a link to a minimal reproduction of the bug
Couldnt get this to work in Stackblitz, it errored out on install so I did it locally: app.component.html:
<button mat-menu-item [disabled]="btnDisabled" click="onClick()">{{btnText}}</button>
app.component.ts:app.component.spec.ts:
Please provide the exception or error you saw
Oddly enough, this fails one step later in the chain but somehow it's failing on the assert on the spy. Not sure its related but thats the closest I could get so far.
Please provide the environment you discovered this bug in
Angular 17 & Material 17 & Spectator 17, Jest as a test runner
package.json:
Do you want to create a pull request?
No