0

Say I've got an expressjs app, app, setup and an endpoint like so: app.get('/endpoint', endPointFunction)

The function is setup like this:

const axios = require('axios');
var endpointFunction = async(req, res) =>{
try{
  const a = await get5LatestAnime();
  console.log(a.titles); 
  const b = await get5LatestManga();
  console.log(b.titles); 
  res.status(200).json({watch: a.titles, read:b.titles});
}catch(err){
  console.log(err); 
  res.status(400).json({err:err.message});
}

};

async function get5LatestAnime(ballot){
 const { data } = await axios.get('https://anime.website.com/'); 
 return data;
}
async function get5LatestManga(confirmationNumber){
  const { data } = await axios.get(`https://manga.website.com/`); 
  return data;
}

So let's say this all prints/works when you run it, but let's say you want to run some unit tests stubbing out ONLY that first axios request.

describe('Moxios', () => {
            
            beforeEach(() => {
                moxios.install();
                moxios.stubRequest('https://anime.website.com', {
                    status: 200,
                    response: [{titles:[
"Naruto", "Bleach", "Fate/Stay Night", "Death Note", "Code Geass"]}]
                });
                
            });

             afterEach(() => {
                moxios.uninstall()
            });
            it('should return a 200 and confirmation status', function () {
                return request(app)
                    .post('/endpoint')
                    .expect(200, {watch: [
"Naruto", "Bleach", "Fate/Stay Night", "Death Note", "Code Geass"], read: [...titles from the manga website]})
                    });
            });
        });

In a similar scenario (of code that I can't post) what happens is moxios stubs the request correctly but other axios requests have a timeout error regardless of how long I allow the timeout to go on for. (Error: Timeout of 10000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves).

If I don't use use moxios (if I comment out moxios related stuff) and I test just the function that's having the timeout everything but what the endpoint that needs requests stubbed works.

Does anyone have any clue how to fix this?

Kerfuffle
  • 11
  • 1

1 Answers1

0

You need to be careful about the url string passed in to moxios.stubRequest method. It should be https://anime.website.com/, NOT https://anime.website.com.

Besides, the response of get5LatestAnime is an array. Because you mock the response as an array:

response: [{ titles: ['Naruto', 'Bleach', 'Fate/Stay Night', 'Death Note', 'Code Geass'] }],

So, you need to access the titles property from a[0].titles, NOT a.titles in your endpointFunction controller.

Here is a complete working example:

app.js:

const axios = require('axios');
const express = require('express');
const app = express();

var endpointFunction = async (req, res) => {
  try {
    const a = await get5LatestAnime();
    console.log(a);
    const b = await get5LatestManga();
    console.log(b);
    res.status(200).json({ watch: a[0].titles, read: b[0].titles });
  } catch (err) {
    console.log(err);
    res.status(400).json({ err: err.message });
  }
};

async function get5LatestAnime(ballot) {
  const { data } = await axios.get('https://anime.website.com/');
  return data;
}
async function get5LatestManga(confirmationNumber) {
  const { data } = await axios.get(`https://manga.website.com/`);
  return data;
}

app.get('/endpoint', endpointFunction);

module.exports = { app };

app.test.js:

const { app } = require('./app');
const moxios = require('moxios');
const request = require('supertest');
const { expect } = require('chai');

describe('Moxios', () => {
  beforeEach(() => {
    moxios.install();
  });

  afterEach(() => {
    moxios.uninstall();
  });
  it('should return a 200 and confirmation status', (done) => {
    moxios.stubRequest('https://anime.website.com/', {
      status: 200,
      response: [{ titles: ['Naruto', 'Bleach', 'Fate/Stay Night', 'Death Note', 'Code Geass'] }],
    });
    moxios.stubRequest('https://manga.website.com/', {
      status: 200,
      response: [{ titles: ['Naruto', 'Bleach', 'Fate/Stay Night', 'Death Note', 'Code Geass'] }],
    });

    request(app)
      .get('/endpoint')
      .expect('Content-Type', 'application/json; charset=utf-8')
      .expect(200)
      .end((err, res) => {
        if (err) {
          return done(err);
        }
        expect(res.body).to.deep.equal({
          watch: ['Naruto', 'Bleach', 'Fate/Stay Night', 'Death Note', 'Code Geass'],
          read: ['Naruto', 'Bleach', 'Fate/Stay Night', 'Death Note', 'Code Geass'],
        });
        done();
      });
  });
});

test result:

  Moxios
[ { titles:
     [ 'Naruto',
       'Bleach',
       'Fate/Stay Night',
       'Death Note',
       'Code Geass' ] } ]
[ { titles:
     [ 'Naruto',
       'Bleach',
       'Fate/Stay Night',
       'Death Note',
       'Code Geass' ] } ]
    ✓ should return a 200 and confirmation status (107ms)


  1 passing (121ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   88.89 |      100 |     100 |   88.89 |                   
 app.js   |   88.89 |      100 |     100 |   88.89 | 13-14             
----------|---------|----------|---------|---------|-------------------
Lin Du
  • 88,126
  • 95
  • 281
  • 483
  • Thanks for taking a crack at it, but I was specifically asking about the situation where you only need the first request (anime) stubbed. I'm running into a problem where it stubs one request but it causes other actual axios requests that are not stubbed to not work. – Kerfuffle Nov 06 '20 at 13:41