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

Async support? #28

Closed
jayeshgangadharan opened this issue Dec 30, 2014 · 12 comments
Closed

Async support? #28

jayeshgangadharan opened this issue Dec 30, 2014 · 12 comments
Labels

Comments

@jayeshgangadharan
Copy link

Can i use node-mocks-http for testing async? for eg: I have this in my router which can be reached through GET /category/list

var getData = function (req, res) {
MongooseCategory.find({}, function (err, docs) {
if (!err) {
res.json(200, { categories: docs });
} else {
res.json(500, { message: err });
}
});
};

In the test
var response = httpMocks.createResponse();
getData(request, response);
console.log(response._getData());

but the response does not contain the json (response comes back later after a few seconds). How can i test this? Any help is much appreciated.

@knowmad
Copy link

knowmad commented Jan 10, 2015

We're having this issue as well. It looks like the problem has been addressed via events. I found this pull request from early last year -- #11. However, as you'll see in my comment, I've been unable to get it working. Hope you'll have better luck!

@frankcash
Copy link

👎 has anyone got this to work with async yet? I will try to meddle more but it'd be awesome if someone else has.

@jayeshgangadharan
Copy link
Author

Nope I couldn't, so moved over to Supertest with sinon for mock/stub.

@howardabrams
Copy link
Collaborator

Not really sure how at this point with really changing its simple interface. I'll be curious if your able to come up with a solution.

On Feb 14, 2015, at 8:50 PM, Frank Cash notifications@github.com wrote:

has anyone got this to work with async yet? I will try to meddle more but it'd be awesome if someone else has.


Reply to this email directly or view it on GitHub.

@estilles
Copy link

@jayeshgangadharan, I know I'm relatively new to this project, but I would like to give my two cents on this issue.

  1. Your idea to use sinon is spot on. That is exactly what you should be using. That said, just like you used sinon with Supertest you could have also done so with node-mocks-http as well.
  2. I believe that within your unit tests you should be testing your code and not third-party code that make async calls to server-side services. Libraries like sinon exist to help us stub and simulate their behavior.

I think my two cents require more explanation ...

In your example I assume MongooseCategory is a Mongoose model. I also assume that, in your test, you are not testing the behavior of the Mongoose model#find() method. As Mongoose consumers, we presume the Mongoose folks have already done that for us. What you are, in fact, testing is your code's within the model#find() method's callback.

The async call to MongooseCategory.find() can be easily simulated with sinon, while still using our response mock.

In the test below I simulate the two possible conditions in the callback (with and without an error);

var MongooseCategory = {
  find: function() {}
}

afterEach(function() {
  MongooseCategory.find.restore();
})

it('shoud return doc', function() {
  var request = mocks.createRequest();
  var response = mocks.createResponse();

  // simulate MongooseCategory.find() returns a doc
  sinon.stub(MongooseCategory, 'find', function(query, callback) {
    callback(null, [{ name: 'value' }]);
  });

  getData(request, response);
  console.log(response._getData());
});

it('shoud return error', function() {
  var request = mocks.createRequest();
  var response = mocks.createResponse();

  // simulate MongooseCategory.find() returns an error
  sinon.stub(MongooseCategory, 'find', function(query, callback) {
    callback('error message');
  });

  getData(request, response);
  console.log(response._getData());
});

I just ran this test using the current version of node-mocks-http and this was the result:

{"categories":[{"name":"value"}]}
  ✓ shoud return doc 
{"message":"error message"}
  ✓ shoud return error 

  2 passing (10ms)

The concept employed above can be easily extrapolated and transferred to any use-case involving async calls.

node-mocks-http intends to simulate the behavior of request and response objects for the purpose of testing your Express route handlers/middleware. It is not opinionated and presumes nothing about the code being tested.

It is therefore, IMHO, each developer's responsibility to mock/stub calls to any async functions/methods that are not part of the unit under test.

As-is, node-mocks-http can be used to test async code, with a little help from libraries like sinon. Providing any other support for testing async code is outside the scope of our project.

@estilles
Copy link

@howardabrams ... I'm closing this issue for now. If anyone believes it requires further discussion, please feel free to reopen.

@chmanie
Copy link

chmanie commented May 29, 2015

This my (first) take on simple async testing with this library:

https://gist.github.com/da3c150cc8fda254a1a5

@estilles
Copy link

@chmanie, that's a nice solution. Thanks for sharing. The solution I provided above intended to use node-mocks-http as-is. That said, in the next version of the project (see our roadmap in issue #54) the mocked response object will be an event emitter (much like Express' response object), so your solution could easily be implemented.

Thanks again for sharing! :-)

@bluehallu
Copy link

What's wrong with this out-of-the-box solution?

var mock_res = httpMocks.createResponse({
    eventEmitter: require('events').EventEmitter
  });

events being the node default events library ofc

@chmanie
Copy link

chmanie commented Jun 14, 2015

Some of the functions (e.g. res.json()) don't call res.end() per default.

EDIT: In the current version (1.4.3) only res.redirect() is missing the emitting if the 'end' event.

@estilles
Copy link

@chmanie, thanks for point that out. We are currently aware of some the current inconsistencies in the implementation. We're in the process of overhauling node-mocks-http, and the 2.0 version should correct all of these inconsistencies. If there's something in particular that you need urgently fixed in the 1.x track just open a new issue and let us know what you need. We will be happy to accommodate you.

@romanlv
Copy link

romanlv commented May 9, 2020

Solution described in #159 seems like the easiest to implement

here is typescript example, works with next.js
https://gist.github.com/romanlv/c12c2541212110968bc92ba19b176d1c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants