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

feat(testing): Provide MockPlatformLocation by default in BrowserTest… #49137

Closed
wants to merge 1 commit into from

Conversation

atscott
Copy link
Contributor

@atscott atscott commented Feb 19, 2023

…ingModule

Tests sometimes do not mock out the PlatformLocation and end up affecting real browser state. This can mean changing the real URL of the browser during a test, updating the History state object, or any number of other stateful operations. This can result in a test unintentionally affecting other tests in the suite because the browser state does not usually get reset before the next test runs. Providing MockPlatformLocation by default prevents these types of accidental test leakages.

In addition, not providing MockPlatformLocation by default led to developers needing to add RouterTestingModule to their test suite to avoid the problems above. This module has spy Location providers which prevent those issues. This commit now makes RouterTestingModule obsolete. Developers can now just use RouterModule.forRoot or provideRouter directly in tests without needing to learn to import additional test providers or modules.

With this, we should consider deprecating RouterTestingModule altogether and migrating developers to RouterModule.forRoot or provideRouter instead. There are some small differences between SpyLocation and MockPlatformLocation that might cause tests to fail after the migration (MockPlatformLocation is actually more correct in its behaviors). If this happens, we can advise developers to also add provideLocationMocks() to their test providers, which would re-provide the SpyLocation like before and should make the tests pass again.

BREAKING CHANGE: MockPlatformLocation is now provided by default in tests. Existing tests may have behaviors which rely on
BrowserPlatformLocation instead. For example, direct access to the window.history in either the test or the component rather than going through the Angular APIs (Location.getState()). The quickest fix is to update the providers in the test suite to override the provider again TestBed.configureTestingModule({providers: [{provide: PlatformLocation, useClass: BrowserPlatformLocation}]}). The ideal fix would be to update the code to instead be compatible with MockPlatformLocation instead.

@atscott atscott added the target: major This PR is targeted for the next major release label Feb 19, 2023
@angular-robot angular-robot bot added detected: breaking change PR contains a commit with a breaking change detected: feature PR contains a feature commit labels Feb 19, 2023
Copy link
Contributor

@AndrewKushnir AndrewKushnir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@atscott atscott added action: merge The PR is ready for merge by the caretaker merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note labels Feb 21, 2023
@atscott
Copy link
Contributor Author

atscott commented Feb 21, 2023

merge assistance: There is a g3 patch that sets ENABLE_MOCK_PLATFORM_LOCATION to true. That will need to be deleted once this is merged.

…ngModule

Tests sometimes do not mock out the `PlatformLocation` and end up
affecting real browser state. This can mean changing the real URL of the
browser during a test, updating the History state object, or any number
of other stateful operations. This can result in a test unintentionally affecting
other tests in the suite because the browser state does not usually get
reset before the next test runs. Providing `MockPlatformLocation` by
default prevents these types of accidental test leakages.

In addition, not providing `MockPlatformLocation` by default led to
developers needing to add `RouterTestingModule` to their test suite to
avoid the problems above. This module has spy `Location` providers which
prevent those issues. This commit now makes `RouterTestingModule`
obsolete. Developers can now just use `RouterModule.forRoot` or
`provideRouter` directly in tests _without_ needing to learn to import
additional test providers or modules.

With this, we should consider deprecating `RouterTestingModule` altogether and
migrating developers to `RouterModule.forRoot` or `provideRouter` instead. There
are some small differences between `SpyLocation` and
`MockPlatformLocation` that might cause tests to fail after the
migration (`MockPlatformLocation` is actually more correct in its
behaviors). If this happens, we can advise developers to also add
`provideLocationMocks()` to their test providers, which would re-provide
the `SpyLocation` like before and should make the tests pass again.

BREAKING CHANGE: `MockPlatformLocation` is now provided by default in tests.
Existing tests may have behaviors which rely on
`BrowserPlatformLocation` instead. For example, direct access to the
`window.history` in either the test or the component rather than going
through the Angular APIs (`Location.getState()`). The quickest fix is to
update the providers in the test suite to override the provider again
`TestBed.configureTestingModule({providers: [{provide: PlatformLocation, useClass: BrowserPlatformLocation}]})`.
The ideal fix would be to update the code to instead be compatible with
`MockPlatformLocation` instead.
@alxhub
Copy link
Member

alxhub commented Feb 22, 2023

This PR was merged into the repository by commit 5dce2a5.

@alxhub alxhub closed this in 5dce2a5 Feb 22, 2023
@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 Mar 25, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker detected: breaking change PR contains a commit with a breaking change detected: feature PR contains a feature commit merge: caretaker note Alert the caretaker performing the merge to check the PR for an out of normal action needed or note target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants