Skip to content

APP_INITIALIZER contract not honoured with TestBed #24218

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

Open
victornoel opened this issue May 31, 2018 · 17 comments
Open

APP_INITIALIZER contract not honoured with TestBed #24218

victornoel opened this issue May 31, 2018 · 17 comments
Labels
area: testing Issues related to Angular testing features, such as TestBed freq1: low P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent type: bug/fix
Milestone

Comments

@victornoel
Copy link
Contributor

victornoel commented May 31, 2018

I'm submitting a...


[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
[ ] Other... Please describe:

Current behavior

When importing a Module providing a promise-based APP_INITIALIZER into a TestBed, the tests are executed before the promise is fully resolved.

There was an issue for this very problem (#16204) but the reporter closed because he found a workaround.

Expected behavior

The promise of an APP_INITIALIZER should be fully resolved, exactly as when running the application that uses this module normally.

Minimal reproduction of the problem with instructions

Hadn't had the time, but I expect that it should be simple to know if is already implemented or not to behave like expected. If yes, I will produce a repro.

What is the motivation / use case for changing the behavior?

Same contract with tests or real app.

Environment


Angular version: 6.0.7
@victornoel
Copy link
Contributor Author

victornoel commented May 31, 2018

For the record, a solution until this is fixed, is to add the following beforeEach in your jasmine tests (after compileComponents() and before createComponent() for example):

  beforeEach(async () => {
    // until https://github.com/angular/angular/issues/24218 is fixed
    await TestBed.get(ApplicationInitStatus).donePromise;
  });

@vicb vicb added area: testing Issues related to Angular testing features, such as TestBed needs reproduction This issue needs a reproduction in order for the team to investigate further labels May 31, 2018
@ngbot ngbot bot added this to the needsTriage milestone May 31, 2018
@victornoel
Copy link
Contributor Author

@vicb are you expecting a repro before this is taken care of? Or is the angular team going to take a look directly at the code.

This doesn't seem to be a bug, regression or a corner case but a very clearly missing feature…

@dydFreeman
Copy link

Any update on this?

P.s: @victornoel your workaround saved my day ; )

@victornoel
Copy link
Contributor Author

@vicb ping? :)

@victornoel
Copy link
Contributor Author

@vicb ping

@vikerman vikerman added type: bug/fix freq1: low severity3: broken and removed needs reproduction This issue needs a reproduction in order for the team to investigate further labels Dec 4, 2018
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Dec 4, 2018
@rgant
Copy link
Contributor

rgant commented Apr 22, 2019

This causes my app confusion regularly in testing. The errors are always so difficult to hunt down because they are cryptic, but I need APP_INITIALIZER to complete before the tests run.

@bjowes
Copy link

bjowes commented Jun 28, 2019

I have been successfully using the workaround for this issue, but after updating to Angular 8 (currently on 8.0.6) it seems the workaround doesn't work anymore. I now have to resort to mocking out the services which should initialize on APP_INITIALIZER in all the unit tests which depend on it, which is quite a hassle.

@singhvivek2503
Copy link

@victornoel Thanks for the workaround. I wasted a day to get to this workaround.
This issue still exists in Angular 8; its amazing how this looong pending issue hasn't been resolved yet!

@s4m0r4m4
Copy link
Contributor

s4m0r4m4 commented Apr 1, 2020

Thumbs up to this - I would classify this as a bug rather than a feature request. Angular should use App Initializers in test the same way it does in serve/production without requiring the user to wait on the donePromise.

Just fyi - For angular 9, the workaround should use TestBed.inject() instead of TestBed.get(). And make sure it comes after TestBed.configureTestingModule(...)

@podikris
Copy link

podikris commented May 5, 2020

I am using angular 6 and the suggested workaround by @victornoel isn't working for me. Any suggestions?

BTW, I am making Http calls inside the promise returned by APP_INITIALIZER's factory, and HttpClientTestingModule is injected in Testbed, i am guessing this could be the issue.

@xavier-experion
Copy link

@podikris Did you find any solution / work around for this. I too have a situation like yours.

@jelbourn jelbourn added P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed severity3: broken labels Oct 1, 2020
@copaste
Copy link

copaste commented Oct 6, 2020

If you test with HttpClientTestingModule it is mandatory to flush each request manualy. To do so just inject HttpTestingController and flush the request like so:

const req = httpController.expectOne(<expected URL>);
req.flush(<request data goes here>);

also after each test make sure that you don't have outstanding requests with:

httpController.verify();

@meriturva
Copy link

If you test with HttpClientTestingModule it is mandatory to flush each request manualy. To do so just inject HttpTestingController and flush the request like so:

const req = httpController.expectOne(<expected URL>);
reqDef.flush(<request data goes here>);

also after each test make sure that you don't have outstanding requests with:

httpController.verify();

Sorry @copaste but issue is not related to HttpClientTestingModule but taton APP_INITIALIZER promise.

@copaste
Copy link

copaste commented Oct 6, 2020

@meriturva Sorry it wasn't clear for me that is not related to HttpClientTestingModule. Because If you have any http calls in the APP_INITIALIZER the promise will never resolve until you flush it.

@kanidjar
Copy link

Up, spent 5 hours trying to understand why my tests were failing while the app was working.

@TrevorKarjanis
Copy link
Contributor

Note, non-initializer providers are instantiated before for the initialization functions complete with victornoels workaround. This is still inconsistent with the actual application behavior.

@stephen-dirtcreative
Copy link

There is no documentation on the pitfalls in testing if using APP_INITIALIZER. Even if the work around doesn't work for every user scenario, that this issue is outstanding for 5 years and there isn't even a mention outside of a ticket in GitHub is very frustrating when trying to figure out what is going wrong. For my case, the work around does get past the hurdle, so thanks to @victornoel for that!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: testing Issues related to Angular testing features, such as TestBed freq1: low P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent type: bug/fix
Projects
None yet
Development

No branches or pull requests