1.0.0-beta.22
https://codesandbox.io/s/4r0ozl6ky7
When I set some attributes set to false, I cannot see them in the generated snapshot
<template>
<div :false-attribute="false" :true-attribute="true">
</template>
<div
false-attribute="false"
true-attribute="true"
/>
<div
true-attribute="true"
/>
This also happens when using Vue in a real browser environment. I think this is to because <div false-attribute="false"> is not actually correct HTML (or rather, is has no meaning in a browser, even if you write it), so JSDOM does not render it (thus it does not appear in the snapshot). This is intentional behavior of Vue/JSDOM/HTML.
Yes, since this is DOM behavior we won't change it in this library.
But I need to pass a prop that is "false" to my ChildComponent.
the prop can be "true", "'myString'", "8", "{ some: 'object' }", "[ 'some', 'array']" or "false"
I understand why it is not rendered. But I don't understand why Snapshots won't contain prop set false
The snapshot is generated by JSDOM. A snapshot it just a comparsion between two wrapper.html that are saved, which is just innerHTML. Since JSDOM y removed the element when you save the snapshot, it will not appear in the snapshot.
But, what about when is a prop? I can't check the prop passed to a stubbed component when is false
context('when is loading', () => {
it('renders card with loading prop true', () => {
isFetching.returns(true);
const wrapper = buildWrapper({ useShallow: true });
const subject = wrapper.find('Card-stub').attributes('loading'); // this returns 'true'
expect(subject).to.eq('true');
});
});
context('when is not loading', () => {
it('renders card with loading prop false', () => {
isFetching.returns(false);
const wrapper = buildWrapper({ useShallow: true });
const subject = wrapper.find('Card-stub').attributes('loading'); // this returns undefined
expect(subject).to.eq('false');
});
});
And my Component:
```vue
:loading="isFetching"
>
...content
You are just testing that your isFetching mock works correctly in that example . The test doesn't actually prove the component is doing what is should be when isFetching is true/false.
Would using mount and making an assertions against the rendered DOM (eg, does some <div id="loading" /> element appear) be an option?
Partially I agree, for this case, I wouldn't like to test if Card component it works, I'd like to see if the isFetching is applied to loading prop of this Card component, btw, using mount it might work, but, it looks that I'm scaping from unit tests
Anyway, what I'm trying to understand is: when the isFetching is false, why the loading prop returns undefined
I did some testing. If the props is true, my html shows like this:
<div id="app" msg="new message"><img alt="Vue logo" src="./assets/logo.png">
<helloworld-stub msg="Welcome to Your Vue.js App" someprop="true"></helloworld-stub>
</div>
if false
<div id="app" msg="new message"><img alt="Vue logo" src="./assets/logo.png">
<helloworld-stub msg="Welcome to Your Vue.js App"></helloworld-stub>
</div>
So in your case, the loading props is not undefined, the loading attribute is.
attributes (code here) just calls the attributes function on a DOM element; which will not return something not present in the rendered HTML (DOM behavior). So that's why it's undefined when a property is false; it doesn't appear in the DOM. This isn't something we can change, it's how the DOM works.
If you really want to assert against the prop, you can hackily access it like this: wrapper.find('helloworld-stub').vm._props.someProp). I would advise against this; both Vue's API and VTU's API may change for Vue 3, and this might no longer work. It's also bad practice - you aren't actually testing anything.
So, your options:
vm._props.isLoading.mount here. It might not be a "true unit test", but the goal is to make sure your components work, not to isolate everything. Hopefully this helps.
Thanks @lmiller1990, u're right, we write tests to make sure that the code works =)
About the .attributes method, I was using because of .props it was returning an empty object.
I'm gonna use mount, it looks better, thank you again
Most helpful comment
I did some testing. If the props is
true, my html shows like this:if false
So in your case, the loading props is not undefined, the loading attribute is.
attributes(code here) just calls theattributesfunction on a DOM element; which will not return something not present in the rendered HTML (DOM behavior). So that's why it's undefined when a property isfalse; it doesn't appear in the DOM. This isn't something we can change, it's how the DOM works.If you really want to assert against the prop, you can hackily access it like this:
wrapper.find('helloworld-stub').vm._props.someProp). I would advise against this; both Vue's API and VTU's API may change for Vue 3, and this might no longer work. It's also bad practice - you aren't actually testing anything.So, your options:
vm._props.isLoading.mounthere. It might not be a "true unit test", but the goal is to make sure your components work, not to isolate everything.Hopefully this helps.