Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mocking Superagent #223

Closed
jamesblack opened this issue Jan 22, 2015 · 20 comments
Closed

Mocking Superagent #223

jamesblack opened this issue Jan 22, 2015 · 20 comments

Comments

@jamesblack
Copy link

Has anyone had any luck getting a mock for superagent that works?

My code looks like


request
        .get("ENDPOINT")
        .accept("json")
        .end(function(err, results) {
          if (err || !results.ok) return res.status(500).send(err || results.status);

          return res.status(200).send(results.body);
        });

It yells at me about all sorts of fun stuff like Buffer of undefined. I found a superagent manual mock on here, but when I install it, it complains that request has no method .get. I don't think the Mock works for the latest superagent, or maybe I don't understand how to use it. does anyone have thoughts?

@khankuan
Copy link

+1

@laurel-taylor
Copy link

getting the same problem. The error is "Cannot read property 'buffer' of undefined" and looks like it's coming from superagent/node_modules/debug/node.js (using version 0.21.0 of superagent) ..I would say it's a problem with https://github.com/visionmedia/debug but there isn't any instance of "buffer" anywhere in debug..

@enocom
Copy link

enocom commented Feb 2, 2015

+1 Same problem here.

@dangerbell
Copy link

I got the mock provided here: http://bl.ocks.org/simenbrekken/b6282f713605b619834f to work by putting it in the __mocks__ folder.

But that mock doesn't provide the convenience methods like get/post/put/etc. I had a similar problem promisifying superagent and getting those functions to work. What I ended up doing is not using the convenience methods and instead using the more constructory method.

e.g. Instead of

request.get('/user').end()

I did

request('GET', '/user').end()

This might be a bit of a pain if you have lots of places to change, but it's been working for me and I don't mind the syntax.

@jennazee
Copy link

FWIW, I only had luck with chaining methods for a POST when I cribbed the definition of superagent from the original source into the mock:

var superagent = jest.genMockFunction().mockImplementation(function(method, url) {
  // callback
  if ('function' == typeof url) {
    return new Request('GET', method).end(url);
  }

  // url first
  if (1 == arguments.length) {
    return new Request('GET', method);
  }

  return new Request(method, url);
})

@pherris
Copy link

pherris commented Apr 17, 2015

I'm using superagent ^1.1.0 and was able to get my tests working with this mock: https://gist.github.com/pherris/aa74aa9b8b1a55ea053b

'use strict';

//mock for superagent - __mocks__/superagent.js

var mockDelay;
var mockError;
var mockResponse = {
  status() { 
    return 200; 
  },
  ok() { 
    return true; 
  },
  get: jest.genMockFunction(),
  toError: jest.genMockFunction()
};

var Request = {
  post() {
    return this;
  },
  get() {
    return this;
  },
  send() {
    return this;
  },
  query() {
    return this;
  },
  field() {
    return this;
  },
  set() {
    return this;
  },
  accept() {
    return this;
  },
  timeout() {
    return this;
  },
  end: jest.genMockFunction().mockImplementation(function(callback) {
    if (mockDelay) {
      this.delayTimer = setTimeout(callback, 0, mockError, mockResponse);

      return;
    }

    callback(mockError, mockResponse);
  }),
  //expose helper methods for tests to set
  __setMockDelay(boolValue) {
    mockDelay = boolValue;
  },
  __setMockResponse(mockRes) {
    mockResponse = mockRes;
  },
  __setMockError(mockErr) {
    mockError = mockErr;
  }
};

module.exports = Request;

My app code:

  request.post(url)
        .send(params)
        .timeout(TIMEOUT)
        .end(function(err, res) {
          if (err) {
            defer.reject(err);
          }
          defer.resolve(res.body);
      });

@screendriver
Copy link
Contributor

This mock is also working for me 👍

@atecarlos
Copy link

Worked for me too! Thanks for sharing

@9Dave9
Copy link

9Dave9 commented Jun 27, 2015

Where exactly do I place this __mocks__folder? I'm having ad hard time figuring this out.

@browniefed
Copy link
Contributor

@9Dave9 copy that mock code, put it in superagent.js in a __mocks__ in the root of where you are telling jest to look for __tests__ folders.

@9Dave9
Copy link

9Dave9 commented Jun 27, 2015

@browniefed - Thank you.

@JoelOtter
Copy link

Can verify that @pherris' mock works on superagent 1.3.0. I'm using CoffeeScript so had to rewrite it in that - here's a Gist in case it's helpful for anyone. Thanks for this, really helped me out. 👍

https://gist.github.com/JoelOtter/b97d207acbbca414baba

@cpojer
Copy link
Member

cpojer commented Oct 16, 2015

The mock that people are using here is working well, so closing this issue.

@cpojer cpojer closed this as completed Oct 16, 2015
@MrNice
Copy link

MrNice commented Feb 6, 2017

If you're using the above mock, please note this bug:

  __setMockError(mockErr) {
    mockErr = mockErr;
  }

Correct it to

  __setMockError(mockErr) {
    //     VV
    mockError = mockErr;
    //     ^^
  }

@pherris
Copy link

pherris commented Feb 7, 2017

thx @MrNice - updated

@MrNice
Copy link

MrNice commented Feb 7, 2017

No worries, eslint's static linter saves the day again 👍

@adewergifosse
Copy link

Hi,
I know it has been a while since this issue has been opened, and closed.
But I used this solution and I ran in a problem while using promises, chaining the .then

Here is my updated version of the mock proposed by @pherris

// mock for superagent - __mocks__/superagent.js

let mockDelay;
let mockError;
let mockResponse = {
  status() {
    return 200;
  },
  ok() {
    return true;
  },
  body: {},
  get: jest.genMockFunction(),
  toError: jest.genMockFunction(),
};

const createRequestStub = (obj) => jest.fn(() => obj);

function Request() {
  let self = this;
  self.mockResponse = mockResponse;
  self.mockDelay = mockDelay;
  self.mockError = mockError;

  self.post = createRequestStub(self);
  self.get = createRequestStub(self);
  self.send = createRequestStub(self);
  self.query = createRequestStub(self);
  self.field = createRequestStub(self);
  self.set = createRequestStub(self);
  self.accept = createRequestStub(self);
  self.timeout = createRequestStub(self);
  self.then = (cb) => {
    return new Promise((resolve, reject) => {
      if (self.mockError) {
        return reject(self.mockError);
      }
      return resolve(cb(self.mockResponse));
    });
  };
  self.end = jest.genMockFunction().mockImplementation(function (callback) {
    if (self.mockDelay) {
      this.delayTimer = setTimeout(callback, 0, self.mockError, self.mockResponse);

      return;
    }

    callback(self.mockError, self.mockResponse);
  });
  //expose helper methods for tests to set
  self.__setMockDelay = (boolValue) => {
    self.mockDelay = boolValue;
  },
  self.__setMockResponse = (mockRes) => {
    self.mockResponse = mockRes;
  },
  self.__setMockError = (mockErr) => {
    self.mockError = mockErr;
  }
};

module.exports = new Request();

It allows for promise chaining, but also have stubs on get, post, etc, to be able to verify how many times it has been called, and the argument passed.

I hope it can be of help to someone

@lbinh89
Copy link

lbinh89 commented Oct 26, 2018

when I change module.exports = Request; to export default Request test run failed. Manual mock look like not work , any solution for this problem. Thanks you

@a8568730
Copy link

a8568730 commented Jun 5, 2019

I found if only mock superagent.get(), can check the answer in how-do-i-mock-async-fetches-with-jest, author is Yevhenii Herasymchuk. He used the syntax sugar jest.fn().mockResolvedValue.

MyComponent.spec.js

import React from 'react'
import superagent from 'superagent-bluebird-promise'
import { shallow } from 'enzyme'
import MyComponent from './'

test('Render the list from ajax', async () => {
  superagent.get = jest.fn().mockResolvedValue({
    body:[
       {id: 1, content: 'AAA'},
       {id: 2, content: 'BBB'}
  ]})

  const wrapper = await shallow(<MyComponent/>)
  expect(wrapper.find('p')).toHaveLength(2)
})

MyComponent.jsx

import React from 'react'
import superagent from 'superagent-bluebird-promise'

export default class MyComponent extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
	responseArr: []
    }
  }
  componentDidMount () {
    superagent.get(THE_REQUEST_URL)
    .then(({ body }) => {
      this.setState({responseArr: body})
    })
   .catch((err) => {
      console.log('Oops! ', err)
    })
  }

  render() {
    return (
      <div>{
          this.state.responseArr.map(item => (
              <p key={item.id}>{item.content}</p>
           ))
       }</div>
    )}
}

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 11, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests