Testing backend communication
Using MSW
The most common answer to the problem of how to test communication with the backend is to mock fetch or axios or whatever library you use for making http requests. However, StackOverflow user jonrsharpe proposes a better method: use msw, the Mock Service Worker. It works by essentially creating a server that intercepts requests on the network level. Here is an example:
The server we have created responds to login requests:
- If the username and password are
alice
andtopsecret
, it responds with a token - If the username and password are
alice
andwrongpassword
, it responds with an error message - Otherwise, it throws an exception, effectively simulating a network error.
That’s it, essentially. You don’t need to mock anything. Whenever your main code attempts to talk to the network, MSW will intercept the request and provide a response.
But there are a few problems.
Initializing Axios
As I explained in my previous post, it isn’t trivial to initialize Nuxt at the beginning of testing, so certain things like the store don’t exist. Likewise, if you are using @nuxtjs/axios
, this.$axios
will also not exist. Therefore, when your component or any part of your code tries to make a request by using this.$axios
, it will stop and give you a message like “Cannot read property ‘post’ of undefined”. I haven’t solved that problem yet. Until I do, what you can do is something like this:
(I have left the MSW part out to concentrate on the problem at hand; but you need to combine the two parts for it to actually work.)
So we kind of “mock” axios, but not with a mock function such as jest.fn()
; instead, we assign it a real instance of Axios.
Unfortunately, this won’t solve all problems. The problem is that @nuxtjs/axios
is not the same as axios
; the former has a little bit more functionality. If your main code uses that additional functionality, such the .setToken()
method, it won’t work during the tests. What you need to do in that case is to mock this additional functionality; for example,
wrapper.vm.$axios.setToken = jest.fn()