Reputation: 2021
I am having trouble figuring out how to test an API call that happens in the "mounted" lifecycle hook.
I have a single file component that is responsible for displaying some information about an "Owner".
This works exactly how I want / expect in the browser.
<template>
<div>
<h3>Owner Information</h3>
<table class="table table-striped table-condensed">
<thead>
<th>Name</th>
<th>Address</th>
<th>Social Security Number</th>
<th>Ownership Percentage</th>
</thead>
<tbody>
<tr :data-owner-id="owner.id" v-for="owner in owners">
<td>{{ owner.name }}</td>
<td>{{ owner.address }}</td>
<td>{{ owner.censored_ssn }}</td>
<td>{{ owner.ownership_percentage }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
principal_id: '',
owners: []
}
},
mounted() {
const el = document.querySelector('#owner-information');
this.principal_id = el.dataset.principal;
var self = this;
axios.get(`/principals/${this.principal_id}.json`).then(response => {
response.data.owners.map((owner) => {
owner.score = '';
owner.link = '';
owner.last_pull_date = '';
self.owners.push(owner);
});
});
.catch(e => {
console.log(e);
});
}
}
</script>
For testing, I am using Karma, Jasmine, and Avoriaz.
Here is a failing test:
import { mount } from 'avoriaz'
import OwnerInformation from '../../app/javascript/packs/OwnerInformation.vue'
describe('OwnerInformation', () => {
let component
beforeAll(() => {
const element = document.createElement('div')
element.setAttribute('id', 'owner-information')
element.setAttribute('data-principal', '84033')
document.body.appendChild(element)
component = mount(OwnerInformation)
component.vm.$mount('#owner-information')
})
it('retrieves owner information from the API', () => {
expect(component.data().owners.length).toBe(1)
})
})
The above expects 1, but gets 0.
So now I figure that I need to stub/mock out my API request in some manner. A quick Google search leads me to moxios. So I install it with Yarn and eventually come up with this. I am not 100% sure where to put moxios.stubRequest, but have tried putting it in beforeAll(), beforeEach(), and inside the "it".
```
import moxios from moxios
import { mount } from 'avoriaz'
import OwnerInformation from '../../app/javascript/packs/OwnerInformation.vue'
describe('OwnerInformation', () => {
let component
beforeAll(() => {
const element = document.createElement('div')
element.setAttribute('id', 'owner-information')
element.setAttribute('data-principal', '12345')
document.body.appendChild(element)
component = mount(OwnerInformation)
component.vm.$mount('#owner-information')
})
beforeEach(() => {
moxios.install()
})
afterEach(() => {
moxios.uninstall()
})
it('retrieves owner information from the API', () => {
moxios.stubRequest('/principals/12345', {
status: 200,
response: {
id: 1, owners: [
{ name: 'Test Owner', address: '123 Test St.', ssn: '123-12-1234', ownership_percentage: 100
}
]
}
})
expect(component.data().owners.length).toBe(1)
})
It appears that the request is not actually be stubbed out. To troubleshoot, I put a console.log statement just before the axios.get() call (which logs out successfully) and I also put a console.log to log out the response, but this one never shows up which makes me think that the axios request is not working and is not getting "intercepted" by moxios.
...
console.log('CALLING API...')
axios.get(`/principals/${this.principal_id}.json`).then(response => {
console.log('***********************')
...
When I run the test I do see a 404, but am unsure why:
01 08 2017 12:49:43.483:WARN [web-server]: 404: /principals/12345.json
To me, it makes most sense to stub out the request at the top of beforeAll()
, but this does not work either.
How can I arrange this so that moxios stubs out the API request and it returns so that my test passes?
Upvotes: 1
Views: 2772
Reputation: 3415
You need to use moxios.wait()
to wait for the moxios request to complete:
/*** note the "done" argument -- you must call this method within wait()! ***/
it('retrieves owner information from the API', (done) => {
moxios.stubRequest('/principals/12345', {
status: 200,
response: {
id: 1, owners: [{ name: 'Test', address: '123 Test St.' }]
}
})
moxios.wait(function() {
expect(component.data().owners.length).toBe(1)
done()
})
})
Upvotes: 3