Plugin mocks#40123
Conversation
|
Pinging @elastic/kibana-app-arch |
|
Pinging @elastic/kibana-platform |
This was also brought up in the original mocks PR When your tests don't have to set custom mock values |
|
Happy to re-open the discussion here. The one thing I didn't investigate was why we can't import mocks with absolute file paths like |
|
This PR still preserves your intended behaviour but with a shorter import statement. import { coreStartMock } from 'ui/new_platform/mocks/cores.test.mocks';Or with plugins: import { mock } from 'ui/new_platform/mocks/cores_and_plugins.test.mocks';But it also ads ability for devs to mock jest.mock('ui/new_platform')In general though, I'm not sure that importing something from that mock and asserting against it is a good idea. In my view, for unit tests we should not even need this mock, devs in their tests should mock whatever they need to mock for testing. I see this as us adding a "global" mock for easier migration to NP, so that plugins can simply stub (not mock) their static imports with
|
This PR allows you to import using absolute path. import 'ui/new_platform/mocks/cores.test.mocks';or import { coreStartMock } from 'ui/new_platform/mocks/cores.test.mocks';I believe to import from core you need to use |
|
yeah I like the absolute and shorter import from moving Between and I don't see any advantages to using (1) above (2). So we have two ways to do the same thing without any benefits. Given that (2) is more powerful, I'd prefer if we remove (1) and only keep (2). |
If we had to pick one, I would actually prefer (1) for the same reason, because (2) is more "powerful". It is more "powerful" because it is easier to do assertions in (2) against But I'm not sure there is any benefit of doing assertions agains That's why I don't see a reason to create any assertions agains The only plugin that was doing assertions against |
💚 Build Succeeded |
I think this is a good point. After discussing this with @streamich we could not think of a good reason someone would have to make assertions against the Our assumption is:
If this assumption is true, I agree that Since it's easier to start with being too restrictive and relaxing it later than the other way around going for option (1) seems like the best choice until our assumption is proven wrong. @elastic/kibana-platform Thoughts? |
lukeelmers
left a comment
There was a problem hiding this comment.
Our assumption is:
- Existing code doesn't need to make assertions against the ui/new_platform module
- New code should be written as a New Platform shim or at the very least receive it's dependencies as parameters. This allows passing a Core mock in your tests without requiring you to mock the ui/new_platform module.
I was previously advocating for the other more "powerful" approach, but I think reading this thread has changed my mind :)
I like the idea of sticking with an approach that enforces good architectural practices for NP code.
Overall this LGTM! I added a few notes, but no major concerns on my end that should block merging.
| import { Plugin } from '.'; | ||
|
|
||
| export type Setup = jest.Mocked<ReturnType<Plugin['setup']>>; | ||
| export type Start = jest.Mocked<ReturnType<Plugin['start']>>; |
There was a problem hiding this comment.
We should already be exporting these ReturnTypes as something like DataSetup from the index.ts file. Probably fine to leave as-is for now to prevent confusion with the legacy/shim data plugin, just wanted to note that here.
src/plugins/__mocks__/mocks.ts
Outdated
| // eslint-disable-next-line @kbn/eslint/no-restricted-paths | ||
| import { dataPluginMock } from '../data/public/mocks'; | ||
|
|
||
| export const pluginsMock = { |
There was a problem hiding this comment.
Do we want/need this global mock for plugins in the new platform? vs importing into helpers.ts whatever plugin setup contracts we need directly from the plugins themselves?
I'm trying to think of what the use case would be here in the NP. Based on the discussion on this PR, I was under the impression we wouldn't do a "global" solution like this in NP (just for ui/new_platform), and instead people would import mocks for core and whichever services their plugin depends on.
So if that assumption is correct, it implies this file would be going away eventually, in which case I'm sure it's needed in the first place.
There was a problem hiding this comment.
I was thinking it could simplify testing if there was one object with all plugin mocks, similar to how there is coreMock with mocks of all Core services.
...instead people would import mocks for core and whichever services their plugin depends on.
Yes, you still need to explicitly import it in the New Platform. The idea is—if your plugin depends on 5 other plugins it is more convenient to import an object of all plugin mocks from one place then have 5 different import statements and construct that object yourself. If you want to be really precise in your tests, you can destructure that object and pick only the needed plugin mocks.
There was a problem hiding this comment.
I think what @lukeelmers is suggesting is not to change any functionality but just to move the contents of this file into src/legacy/ui/public/new_platform/__mocks__/helpers.ts. I think that's a good idea 👍 Like you said, it makes sense to get all the plugin mocks when you're consuming NP from legacy ui/new_platform but if all the mocking logic lives in the same file, then we can just delete that file once the migration is complete.
💔 Build Failed |
src/plugins/__mocks__/mocks.ts
Outdated
| // eslint-disable-next-line @kbn/eslint/no-restricted-paths | ||
| import { dataPluginMock } from '../data/public/mocks'; | ||
|
|
||
| export const pluginsMock = { |
There was a problem hiding this comment.
I think what @lukeelmers is suggesting is not to change any functionality but just to move the contents of this file into src/legacy/ui/public/new_platform/__mocks__/helpers.ts. I think that's a good idea 👍 Like you said, it makes sense to get all the plugin mocks when you're consuming NP from legacy ui/new_platform but if all the mocking logic lives in the same file, then we can just delete that file once the migration is complete.
rudolf
left a comment
There was a problem hiding this comment.
I'd lean towards removing the src/plugins/__mocks__/mocks.ts file but happy either way.
💚 Build Succeeded |
💚 Build Succeeded |
* Plugin mocks (#40123) * test: 💍 add ability to mock plugins in ui/new_platform * chore: 🤖 delete olds NP backdoor mock * test: 💍 normalize plugin contract naming in line with Core * test: 💍 use mock from ui/new_platform instead of core * test: 💍 remove ui/new_platform mocking from Core * chore: 🤖 leave only one mocking strategy for ui/new_platform * style: 💄 format according to Prettier * chore: 🤖 remove /src/plugins/__mocks__ folder * fix: 🐛 move mock to correct folder * test: 💍 fix test mock
Summary
ui/new_platform.ui/new_platformby simplyjest.mock('ui/new_platform')Checklist
Use
strikethroughsto remove checklist items you don't feel are applicable to this PR.This was checked for cross-browser compatibility, including a check against IE11Any text added follows EUI's writing guidelines, uses sentence case text and includes i18n supportDocumentation was added for features that require explanation or tutorialsUnit or functional tests were updated or added to match the most common scenariosThis was checked for keyboard-only and screenreader accessibilityFor maintainers
This was checked for breaking API changes and was labeled appropriatelyThis includes a feature addition or change that requires a release note and was labeled appropriatelyDev Docs
ui/new_platformAs we move more services to the New Platform we refactor existing code to internally use
If your Jest tests break because something not immediate to your plugin was refactored to use
ui/new_platformyou can useto stub
ui/new_platformmodule and make your existing Jest work temporarily while you are refactoring them for the New Platform.