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

defer: change detection & tick doesn't render deferred component in unit test #53686

Closed
GeorgeHulpoi opened this issue Dec 22, 2023 · 9 comments
Assignees
Labels
area: core Issues related to the framework runtime area: docs Related to the documentation core: defer Issues related to @defer blocks.
Milestone

Comments

@GeorgeHulpoi
Copy link

GeorgeHulpoi commented Dec 22, 2023

Which @angular/* package(s) are the source of the bug?

core

Description

In a unit test, if @defer is conditional on a variable, change detection and tick have no effect in fakeAsync.

Please provide a link to a minimal reproduction of the bug

https://github.com/GeorgeHulpoi/ng-defer-testing-bug

Please provide the exception or error you saw

22 12 2023 15:50:45.368:WARN [karma]: No captured browser, open http://localhost:9877/
22 12 2023 15:50:45.387:INFO [karma-server]: Karma v6.4.2 server started at http://localhost:9877/
22 12 2023 15:50:45.388:INFO [launcher]: Launching browsers Chrome with concurrency unlimited
22 12 2023 15:50:45.405:INFO [launcher]: Starting browser Chrome
22 12 2023 15:50:46.034:INFO [Chrome 120.0.0.0 (Windows 10)]: Connected on socket 2kdLNhsoLG81op3hAAAB with id 94279556
Chrome 120.0.0.0 (Windows 10) Snackbar Service it should render component FAILED
        Expected '<button>show</button><!--container--><!--container-->' to contain '<test>'.
            at <Jasmine>
            at UserContext.apply (src/app/test.spec.ts:43:49)
            at UserContext.apply (node_modules/zone.js/fesm2015/zone-testing.js:1987:30)
            at _ZoneDelegate.invoke (node_modules/zone.js/fesm2015/zone.js:368:26)
            at ProxyZoneSpec.onInvoke (node_modules/zone.js/fesm2015/zone-testing.js:273:39)
Chrome 120.0.0.0 (Windows 10): Executed 2 of 2 (1 FAILED) (0.119 secs / 0.035 secs)
TOTAL: 1 FAILED, 1 SUCCESS

Please provide the environment you discovered this bug in (run ng version)

_                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/


Angular CLI: 17.0.8
Node: 20.9.0
Package Manager: npm 10.1.0
OS: win32 x64

Angular: 17.0.8
... animations, cli, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1700.8
@angular-devkit/build-angular   17.0.8
@angular-devkit/core            17.0.8
@angular-devkit/schematics      17.0.8
@schematics/angular             17.0.8
rxjs                            7.8.1
typescript                      5.2.2
zone.js                         0.14.2

Anything else?

No response

@crisbeto
Copy link
Member

There are some utilities to make testing deferred blocks easier: https://angular.dev/guide/defer#testing

@GeorgeHulpoi
Copy link
Author

There are some utilities to make testing deferred blocks easier: https://angular.dev/guide/defer#testing

@crisbeto These utilities force me to manually trigger the defer process when instead Angular should trigger this process.

@JeanMeche JeanMeche added area: core Issues related to the framework runtime core: defer Issues related to @defer blocks. labels Dec 22, 2023
@ngbot ngbot bot added this to the needsTriage milestone Dec 22, 2023
@JoostK
Copy link
Member

JoostK commented Dec 22, 2023

@defer relies on dynamic module loading, which is async by definition and cannot be flushed synchronously in fakeAsync stacks. You'll have to use a native async function for your test and await fixture.whenStable() instead of performing tick.

@GeorgeHulpoi
Copy link
Author

GeorgeHulpoi commented Dec 22, 2023

@defer relies on dynamic module loading, which is async by definition and cannot be flushed synchronously in fakeAsync stacks. You'll have to use a native async function for your test and await fixture.whenStable() instead of performing tick.

@JoostK I tried using fixture.whenStable() and doesn't seem to work. Tried in combination with fixture.whenRenderingDone() and the test fails.

@JoostK
Copy link
Member

JoostK commented Dec 22, 2023

I digged into this a bit more and found that it comes down to how TestBed uses manual triggering of defer blocks. For the behavior you are expecting you need to configure the following:

    TestBed.configureTestingModule({
      // ...
      deferBlockBehavior: DeferBlockBehavior.Playthrough,
    });

Doing so does then actually work with fakeAsync, likely because of how the component is JIT compiled. I would still recommend not to depend on fakeAsync in this case.

@JoostK JoostK added the area: docs Related to the documentation label Dec 22, 2023
@GeorgeHulpoi
Copy link
Author

Yeap, that was the issue. Seems like the documentation needs improvement on Deferrable Views / Testing

@atscott
Copy link
Contributor

atscott commented Dec 22, 2023

I think it's fair to question whether DeferBlockBehavior.Manual should be the default behavior for TestBed. While fakeAsync might not be a great recommendation, I think it's reasonable to make the test async and have await fixture.whenStable() instead. While defer is in developer preview, it's good to gather this type of feedback. I don't think we really know what's the more common/desired behavior for tests yet. Do developers really want to manually trigger the defer behavior every time or are there just a few tests around this with Manual and the rest want Playthrough?

// cc @jessicajaniuk @AndrewKushnir

@JoostK
Copy link
Member

JoostK commented Dec 22, 2023

I was certainly surprised by the current behavior, I'd expected the opposite as well.

jessicajaniuk pushed a commit to jessicajaniuk/angular that referenced this issue Jan 17, 2024
This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: angular#53686
jessicajaniuk pushed a commit to jessicajaniuk/angular that referenced this issue Jan 17, 2024
This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: angular#53686
dylhunn pushed a commit that referenced this issue Jan 17, 2024
…#53956)

This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: #53686

PR Close #53956
ChellappanRajan pushed a commit to ChellappanRajan/angular that referenced this issue Jan 23, 2024
…angular#53956)

This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: angular#53686

PR Close angular#53956
rlmestre pushed a commit to rlmestre/angular that referenced this issue Jan 26, 2024
…angular#53956)

This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: angular#53686

PR Close angular#53956
danieljancar pushed a commit to danieljancar/angular that referenced this issue Jan 26, 2024
…angular#53956)

This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: angular#53686

PR Close angular#53956
amilamen pushed a commit to amilamen/angular that referenced this issue Jan 26, 2024
…angular#53956)

This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: angular#53686

PR Close angular#53956
nikvarma pushed a commit to nikvarma/angular that referenced this issue Jan 31, 2024
…angular#53956)

This inverts the default behavior of test bed to use playthrough for defer blocks instead of manual.

fixes: angular#53686

PR Close angular#53956
@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 Feb 17, 2024
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 area: docs Related to the documentation core: defer Issues related to @defer blocks.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants