Has anyone had any luck getting a mock for superagent that works?
My code looks like
.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?
+1
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..
+1 Same problem here.
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.
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);
})
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);
});
This mock is also working for me :+1:
Worked for me too! Thanks for sharing
Where exactly do I place this __mocks__folder? I'm having ad hard time figuring this out.
@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.
@browniefed - Thank you.
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. :+1:
The mock that people are using here is working well, so closing this issue.
If you're using the above mock, please note this bug:
__setMockError(mockErr) {
mockErr = mockErr;
}
Correct it to
__setMockError(mockErr) {
// VV
mockError = mockErr;
// ^^
}
thx @MrNice - updated
No worries, eslint's static linter saves the day again 馃憤
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
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
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>
)}
}
Most helpful comment
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
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