简体   繁体   中英

How do you use both moxios and supertest's request on an endpoint that has 2 axios requests one that needs to be stubbed and one that shouldn't?

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?

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             
----------|---------|----------|---------|---------|-------------------

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM