I want to test that a BootstrapVue table is rendered correctly based on the data provided by an API. As part of this, I've mocked the fetch function. When I provide the data statically using the loadItems() method, it works fine - 3 rows are rendered. But when I instead swap it to using the API calling method getData() - the rows aren't rendered.
The mocking of fetch appears to work as the API response is logged successfully, but it doesn't seem to make it to the data option of the Vue component.
The Vue component to test:
// MenuTable.vue
<template>
<div>
<b-table class="table"
:items="items" :fields="fields">
</b-table>
</div>
</template>
<script>
export default {
methods: {
getData() {
fetch('https://www.myexampleapi.com/menu', {
method: 'GET',
mode: 'cors',
})
.then((response) => response.json())
.then((data) => {
console.log(data);
this.items = data;
})
.catch((error) => {
this.error = error.message;
console.log(error);
});
},
loadItems() {
return [
{ cost: 10, food: 'Spaghetti' },
{ cost: 20, food: 'Pizza' },
{ cost: 30, food: 'Hamburger' },
];
},
},
created() {
this.items = this.loadItems(); // load items statically
this.getData(); // load items from API
},
data() {
return {
fields: ['food', 'cost'],
items: [],
};
},
};
</script>
The test file:
// MenuTable.spec.js
import { mount, createLocalVue } from '@vue/test-utils';
import MenuTable from '@/components/MenuTable.vue';
// eslint-disable-next-line no-unused-vars
import { BootstrapVue, BButton, BTable, BRow } from 'bootstrap-vue';
// create an extended `Vue` constructor
const localVue = createLocalVue();
// install plugins as normal
localVue.use(BootstrapVue);
describe('Table.vue Buttons Test', () => {
let wrapper = null;
// SETUP - run before to each unit test
beforeEach(() => {
global.fetch = jest.fn(() => Promise.resolve({
json: () => Promise.resolve([
{ cost: 10, food: 'Spaghetti' },
{ cost: 20, food: 'Pizza' },
{ cost: 30, food: 'Hamburger' },
]),
}));
// render the component
wrapper = mount(MinimalTable, {
localVue,
});
});
// TEARDOWN - run after to each unit test
afterEach(() => {
jest.resetModules();
jest.clearAllMocks();
jest.restoreAllMocks();
wrapper.destroy();
});
it('renders three rows', () => {
const tableComponent = wrapper.findAll('tbody > tr');
console.log(tableComponent.length);
expect(tableComponent.length).toEqual(3);
});
});
I've made sure it's not a case of shallow mounting by using mount instead, and I think I've made sure that the test awaits a response from the API response by using Promises.
How come the API response data can be logged, but not assigned to the items data variable?