How can I use nock.js to mock node-webshot requests? - node.js

What is proper way to mock requests sent by node Webshot during a test using nock.js?
I tried following code to capture mocked response of http://example.com/foo.html as foo.png but the mock doesn't seem to work.
const nock = require("nock");
const webshot = require("webshot");
describe("mock webshot request", function(){
this.timeout(20000);
beforeEach(function(){
nock("http://example.com").persist().get("/foo.html").reply(200, "<h1>Foo</h1>");
});
afterEach(function () {
nock.cleanAll();
});
it("captures mocked response", function(done){
webshot("http://example.com/foo.html", "foo.png",function(err) {
nock.isDone();
if(!err) done();
});
});
});
Edit:
The solution was to pass mocked response body to Webshot rather than url:
webshot("<h1>Foo</h1>", ...

Nock expects the http request to happen in the same process.
Note: node-webshot is a wrapper for PhantonJS which run in another process.
In your case Nock is setup in one process, but the http request happens in another process. So you cannot mock http request done by node-webshot like the way your are currently doing.
What you need is support for mocking http request built into node-webshot i.e you will have to add this feature to node-webshot if it doesn't have it.

Related

nodejs nock http get always returns 503

I want to use nock for testing some http calls but it always retunrs 503 service unavailable
describe('BASIC API AUTH TESTS', function() {
'use strict';
before(async () => {
if (!nock.isActive()) nock.activate();
});
after(async() => {
nock.cleanAll();
await helpers.removeTestUsers(mongoDb);
});
it('should return nock response', async() => {
if (!nock.isActive()) nock.activate();
nock('http://zombo.com').get('/').times(1).reply(200, 'Ok');
http.get('http://zombo.com/'); // expected 200 got 503 service unavailable
console.log('nock.pendingMocks(): ', nock.pendingMocks()); // [ 'GET http://zombo.com:80/' ]
});
what is wrong?
testrunner: mocha
node version: 8.12
nock: 13.0.4
This issue is most likely related to the fact that you're not waiting for the request to respond (via Nock) before exiting the tests. Therefore nock.cleanAll(); in your after block is removing your nock and the http.get is attempting a live call.
If you want to stick with native Node http, you need to ditch async (or get fancy with Promises). Node docs have an example on how to use callbacks to wait for the response, then you can call the Mocha done function.
If you want to stick with async, I recommend an HTTP client lib that support promises, then await the request.

MochaJS sending HTTP Request in after hook

I'm trying to send a http delete request to my web server in Mocha's after hook. Here's the relevant code:
after(function() {
console.log('here at after');
request.del('http://localhost:3000/api/deleteAllTasks', function(req, res) {
console.log(req);
});
});
The problem is that the delete endpoint is never being hit. It console.logs "here at after" but never console.logs the request in the callback for request.del. I'm not sure what is causing this; I know the endpoint works as I've sent curl requests to it successfully. Anyone have any ideas? Ultimately, I want this endpoint to clear the DB after this particular test suite runs.
Betting that your script is ending before the asynchronous request is actually made. Try changing your after(function() {... to include the "done" parameter like after(function(done) {... and calling done() within the inner callback.
Here is a new after block that will make your test work. leetibbett is completely correct.
after(function(done) {
console.log('here at after');
request.del('http://localhost:3000/api/deleteAllTasks', function(err, res) {
console.log(res);
done();
});
});

expect (js) not working inside superagent (js)

I'm trying to do TDD for the Rest APIs that I've been creating. New to NodeJS.
I've created a Rest API, and on the response I want to perform all the expect checks. To make an HTTP request I'm using SuperagentJS (also tried RequestJS).
Here is how my code looks like (Snippet only, not whole code)
var expect = require("chai").expect;
var request = require("superagent");
describe("Creation of New Entity", function(){
it("Create a New Entity", function(){
request
.get("http://localhost")
.end(function(err, httpResponse){
expect("1234").to.have.length(3);//equals(500);
expect(200).to.equals(200);
});
});
});
No matter what I try, mocha always gives successful result. (All test cases passed)
Please tell what I'm missing here. What should I do to implement test cases on httpRespnse. I'm sure that request is working fine, because whenever I use console.log(httpResponse.text), it is returning the default apache home page.
All networking in node.js is asynchronous, therefore you must use the mocha asynchronous flavor of it("Create a New Entity", function(done) { and call the done callback when your test is done.
var expect = require("chai").expect;
var request = require("superagent");
describe("Creation of New Entity", function(){
it("Create a New Entity", function(done){
request
.get("http://localhost")
.end(function(err, httpResponse){
expect(err).not.to.exist();
expect("1234").to.have.length(3);//equals(500);
expect(200).to.equals(200);
done()
});
});
});

Are the req and res objects somehow accessible globally in NodeExpress?

req.session.username = user.username;
I'm using supertest to test route handling. In my log in handling code I have the following if a user logs in successfully -
req.session.username = user.username;
But in the supertest call back function I don't have access to the req object.
request(app)
.post('/login')
.send({username: 'dummy_username', password: 'valid_password'})
.end(function(err, res){
if (err) { return done(err); }
expect(err).toBe(null);
expect(res.status).toEqual(200);
done();
});
I would like to add in something like expect(req.session.username).toBe('dummy_username') but obviously I can't I do this when req is not available to me. So is there a way of referencing the req object?
Supertest is for testing the responses only, since testing the request (and the server-side manipulations thereof) would be testing implementation details instead of behavior. supertest isn't the right tool for this job. You can write pure unit tests for some of your server side functions, OR you can have the /login route include the user's information in the response body (which is typical) and have supertest verify that information matches what was in the request.

Mocking using mocha in NodeJs

How can I mock a client and a server in Mocha using NodeJs.
Specifically, I have the following code:
app.post ('path name', function (req, res) {
// Some Action
res.send(response);
});
I want to mock the req, res parameters and test res (status, header, message).
Mocha itself doesn't provide mock/stub/spy type functionality. Sinon is a popular library that does. The home page includes examples of testing ajax as well as their Fake XMLHTTPRequest object.
I found Node-Fakeweb useful
var request = require('request');
// Mocking a client request
request.get({ uri: 'URI', body: 'body' }, function (err, resp, body) {
// Some Action
});
});
You can use mocha with supertest to mock a request. Here is a wonderful tutorial about how to do it:
http://thewayofcode.wordpress.com/2013/04/21/how-to-build-and-test-rest-api-with-nodejs-express-mocha/

Resources