Open k-ode opened 8 years ago
This is pretty much the default if you don't register the child components. If you want to block those registrations you can do it with a component loader.
ko.components.loaders.splice(1, 0, {
getConfig(name, callback) {
const isSUT = name === '_SUT' // this is the name the tester uses to register components
const emptyComponentConfig = { template: document.createElement('div') }
callback(isSUT ? null : emptyComponentConfig)
}
})
We insert at the 2nd position in the array to preserve $.fn.getComponentParams
which
uses a component loader itself to intercept the params. See here. Now you can go one step farther and assert your child components were passed the correct params.
const parent = {
viewModel() { this.childText = 'foo' },
template: '<child params="text: childText"></child>'
}
const $parent = renderComponent(parent)
const $child = $('child', $el)
$child.getComponentParams() === { text: 'foo' }
This could — and should — be incorporated into the api somehow.
Thanks for the clarification! That's very useful information.
However, I forgot to mention that we use the component-binding syntax for a lot for our sub components. And while it is true that custom elements are ignored if they are not registered, the component binding actually complains with Uncaught Error: Unknown component 'todo'
.
We have to use the component binding sometimes because - unlike custom elements - it can be used as a virtual node. This is important if you use something like flexbox which doesn't work right with the extra dom elements that a custom element brings. It's also useful if you have to pass a lot arguments to a component, then you can just pass it as a object in the parent view model.
The custom loader you outlined does solve this, I just wanted to clarify our use case.
I had to change the argument to template to an array though.
ko.components.loaders.splice(1, 0, {
getConfig(name, callback) {
const isSUT = name === '_SUT'; // this is the name the tester uses to register components
const emptyComponentConfig = { template: [document.createElement('div')] };
callback(isSUT ? null : emptyComponentConfig);
}
});
One of the nice things about testing React components with Enzyme is that you can test your components as shallow. In this case, only the top level component gets rendered and all child components are ignored. This makes a lot of sense for unit testing, since you want to test your components as small, independent parts.
It would be nice if you could just call
renderShallowComponent(...)
, but I'm guessing that would also be really involved. I can't say I have any idea how this would be implemented, maybe override the component binding somehow?A simpler method would be an option to ignore certain components. So if you have a TodoList you could do:
These sub components would be registered as empty components. This is what I currently do in a before-call, but it would be tidier to have the functionality built in.
Thoughts?