3 min read

In this article by Andrea Passaglia, the author of the book Vue.js 2 Cookbook, will cover stubbing external API calls with Sinon.JS.

(For more resources related to this topic, see here.)

Stub external API calls with Sinon.JS

Normally when you do end-to-end testing and integration testing you would have the backend server running and ready to respond to you. I think there are many situations in which this is not desirable. As a frontend developer you take every opportunity to blame the backend guys.

Getting started

No particular skills are required to complete this recipe except that you should install Jasmine as a dependency.


How to do it…

First of all let’s install some dependencies, starting with Jasmine as we are going to use it to run the whole thing.

Also install Sinon.JS and axios before continuing, you just need to add the .js files.

We are going to build an application that retrieves a post at the click of a button. In the HTML part write the following:

<div id="app">
<button @click="retrieve">Retrieve Post</button>
<p v-if="post">{{post}}</p>
</div>

The JavaScript part instead, is going to look like the following:

const vm = new Vue({
el: '#app',
data: {
post: undefined
},
methods: {
retrieve () {
axios
.get('https://jsonplaceholder.typicode.com/posts/1')
.then(response => {
console.log('setting post')
this.post = response.data.body
})
}
}
})

If you launch your application now you should be able to see it working.

Now we want to test the application but we don’t like to connect to the real server. This would take additional time and it would not be reliable, instead we are going to take a sample, correct response from the server and use it instead.

Sinon.JS has the concept of a sandbox. It means that whenever a test start, some dependencies, like axios are overwritten. After each test we can discard the sandbox and everything returns normal.

An empty test with Sinon.JS looks like the following (add it after the Vue instance):

describe('my app', () => {
let sandbox
beforeEach(() => sandbox = sinon.sandbox.create())
afterEach(() => sandbox.restore())
})

We want to stub the call to the get function for axios:

describe('my app', () => {
let sandbox
beforeEach(() => sandbox = sinon.sandbox.create())
afterEach(() => sandbox.restore())
it('should save the returned post body', done => {
const resolved = new Promise(resolve =>
r({ data: { body: 'Hello World' } })
)
sandbox.stub(axios, 'get').returns(resolved)
...
done()
})
})

We are overwriting axios here. We are saying that now the get method should return the resolved promise:

describe('my app', () => {
let sandbox
beforeEach(() => sandbox = sinon.sandbox.create())
afterEach(() => sandbox.restore())
it('should save the returned post body', done => {
const promise = new Promise(resolve =>
resolve({ data: { body: 'Hello World' } })
)
sandbox.stub(axios, 'get').returns(resolved)
vm.retrieve()
promise.then(() => {
expect(vm.post).toEqual('Hello World')
done()
})
})
})

Since we are returning a promise (and we need to return a promise because the retrieve method is calling then on it) we need to wait until it resolves.

We can launch the page and see that it works:

How it works…

In our case we used the sandbox to stub a method of one of our dependencies. This way the get method of axios never gets fired and we receive an object that is similar to what the backend would give us.

Stubbing the API responses will get you isolated from the backend and its quirks. If something goes wrong you won’t mind and moreover you can run your test without relying on the backend running and running correctly.

There are many libraries and techniques to stub API calls in general, not only related to HTTP. Hopefully this recipe have given you a head start.

Summary

In this article we covered how we can stub an external API class with Sinon.JS.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here