I'm trying to test a computed method that depends on other computed values within the wrapper
However, when I stub those computed values dependencies using the newly added setComputed method the computed method that I'm trying to test does not update.
Example failing test:
describe('formattedValue', () => {
it('updates with specified format from other computed value', () => {
wrapper.setComputed({
format: 'date_format'
});
console.log('format', wrapper.vm.format); // outputs 'date_format' as expected
assert.equal(wrapper.vm.formattedValue, '12/4/18'); //fails
Example method under test:
formattedValue () {
let formattedValue = this.rawData;
switch (this.format) {
case 'date_format':
formattedValue = moment.utc(moment.unix(this.rawData)).format(this.dateFormatString);
break;
}
return formattedValue;
}
Hey @jonnyparris ,
I just tried this out and it seems to be working fine for me. One thing I noticed was you not only have to shallow or mount your component, but you must _use_ the computed value in the <template> section of your component - otherwise Vue doesn't even bother to updated the new computed value.
Maybe you aren't using {{ format }} in your template? Does that help?
If you can post the component you are testing and the entire test that might help too (like where you are calling mount or shallow on your component.
Here is my working example. Note that removing {{ format }} causes the test to fail, since the value is never initially computed.
import { mount } from 'vue-test-utils'
import App from './App'
describe('App', () => {
it('works', () => {
const wrapper = mount(App)
wrapper.setComputed({ format: 'date_format' })
expect(wrapper.vm.formattedValue).toEqual('updated')
})
})
<template>
<div id="app">
{{ format }}
</div>
</template>
<script>
export default {
name: 'app',
computed: {
format () {
return 'placeholder'
},
formattedValue () {
let formattedValue = ''
switch (this.format) {
case 'date_format':
formattedValue = 'updated'
break
}
return formattedValue
}
}
}
</script>
Thanks for the quick reply!
I am using the computed values in the template as part of v-if and styling conditions. Moreover, the component functions as intended regardless of the failing test.
After inserting some console logs to verify values in both the component and the unit test, it seems as though the setComputed does override the specified values but that doesn't trigger a reactive update to the dependent method under test.
Here's a more expanded snippets that may help to diagnose what's wrong:
import assert from 'assert';
import { shallow } from 'vue-test-utils';
import DatatableCellValue from '~/components/DatatableCellValue';
import dummyData from '~/static/thp_smaller_dummy_response.json';
describe('DatatableCellValue.vue', () => {
let wrapper;
wrapper = shallow(DatatableCellValue, {
propsData: {
row: dummyData.data[0],
column: dummyData.columns[0]
}
});
// TODO - Get this test working.
describe('computed properties', () => {
describe('formattedColumnValue', () => {
it('returns cell value according to self-described column formatting presets', () => {
// ----------- no specified format -----------
let testColumnName = 'publisher';
console.log('raw before', wrapper.vm.rawCellData); // => 3520
wrapper.setComputed({
columnFormat: 'unspecified_format',
rawCellData: dummyData.data[0][testColumnName]
});
console.log('raw after', wrapper.vm.rawCellData); // => monkeys
console.log('format', wrapper.vm.columnFormat); // => unspecified_format
console.log('formatted', wrapper.vm.formattedColumnValue); // => 3520
assert.equal(wrapper.vm.formattedColumnValue, 'monkeys'); // => fail
});
});
});
});
component:
<template>
<div class="wrapper">
<div v-if="columnFormat === 'compound' && row[column.name] !== undefined && rawCellData.hyperlink">
<a
:href="rawCellData.hyperlink" rel="noopener"
v-tooltip.right="rawCellData.additional_info"
:style="{ color: rawCellData.color }"
>
<span class="cell-value" :style="{ color: rawCellData.color }">
{{ formattedColumnValue }}
</span>
</a>
</div>
<div v-else>
<span class="cell-value">
{{ formattedColumnValue }}
}
</span>
</div>
</div>
</template>
<script>
import moment from 'moment';
import { VTooltip } from 'v-tooltip';
export default {
name: 'DatatableCellValue',
directives: {
tooltip: VTooltip
},
props: {
row: {
type: Object,
required: true
},
column: {
type: Object,
required: true
},
dateFormatString: {
type: String,
default: 'YYYY-MM-DD HH:mm:ss'
}
},
data () {
return {
};
},
computed: {
columnFormat () {
if ('format' in this.column) {
return this.column.format;
} else {
return 'unspecified_format';
}
},
rawCellData () {
return this.row[this.column.name];
},
formattedColumnValue () {
let formattedValue = this.rawCellData;
console.log('testyMcTestFace raw', this.rawCellData); // => 3520
switch (this.columnFormat) {
case 'date_as_long':
formattedValue = moment.utc(moment.unix(this.rawCellData)).format(this.dateFormatString);
break;
case 'compound':
formattedValue = this.rawCellData.display_value;
break;
}
return formattedValue;
}
}
};
</script>
Thanks for the bug report 馃檪
Can you make a minimal reproduction please, it makes it much easier to debug
@jonnyparris did you solve your problem? Was it an issue with setComputed, or with your component logic?
Same issue in my case:
Here is a little reproduction of my component
computed: {
...mapGetters([
'isTeamAdmin'
]),
placeholder() {
return this.isTeamAdmin ? 'Leader' : 'inboxMember'
}
}
test.only('placeholder computed is Leader if isTeamAdmin is true', () => {
wrapper.setComputed({ isTeamAdmin: true });
expect(wrapper.vm.placeholder).toContain('Leader');
});
Thanks @disitec . I think yours is a seperate issue to @jonnyparris , I'm moving it out to its own issue.
Haven't forgotten but haven't had time to revisit this just yet...
I believe this will be fixed in https://github.com/vuejs/vue-test-utils/commit/ebccc8dc686223003771022a00fa932e03378fc4
This will be released in beta.9. If this doesn't fix the issue, feel free to reopen.