Unit Testing Azure Mobile App (Node.js) Locally - node.js

Please don't tell me I should have been testing before now. I don't disagree, and that's not the point of this question. If it helps, assume I'm doing TDD perfectly and I'm asking this question about a brand new project. ;-)
I've been developing an Azure Mobile App with a Node.js backend for some time now. I have done so completely dependent on Microsoft hosting the service (which I think makes sense). Now, though, I'd like to have some unit tests running against my code, but I'm at a loss for how to get from a functional, Microsoft-hosted Azure Mobile App to a locally-hosted version where I can run my tests.
A big assumption here is that the testing will run much faster if I'm running them locally. A lot of my code interacts with a SQL Server database, so please tell me if this is an incorrect assumption.
Anyway, I've gotten Node.js and NPM set up on my Mac. I've gone through some basic tutorials on creating a Node.js site from scratch, and I got the ubiquitous "Hello World" Node.js website working locally. I even apparently got a basic Azure Mobile site up and running (at least, I got the "This mobile app has been successfully created" homepage to show up).
I've also done some reading on Mocha and Chai for Unit Testing in Node.js. I even got through some of their first examples and had some simple tests working.
What's confusing me is how to move from the super-basic Mocha test examples to more real-world testing of my actual code.
For instance, here's a Mocha test example (taken from semaphore):
var expect = require("chai").expect;
var converter = require("../app/converter");
describe("Color Code Converter", function() {
describe("RGB to Hex conversion", function() {
it("converts the basic colors", function() {
var redHex = converter.rgbToHex(255, 0, 0);
var greenHex = converter.rgbToHex(0, 255, 0);
var blueHex = converter.rgbToHex(0, 0, 255);
expect(redHex).to.equal("ff0000");
expect(greenHex).to.equal("00ff00");
expect(blueHex).to.equal("0000ff");
});
});
describe("Hex to RGB conversion", function() {
it("converts the basic colors", function() {
var red = converter.hexToRgb("ff0000");
var green = converter.hexToRgb("00ff00");
var blue = converter.hexToRgb("0000ff");
expect(red).to.deep.equal([255, 0, 0]);
expect(green).to.deep.equal([0, 255, 0]);
expect(blue).to.deep.equal([0, 0, 255]);
});
});
});
It's no real surprise that this code will fail until ../app/converter.js is created with the appropriate functions exported. Ok, so I try to adapt that kind of thinking to, say, my Login method, and I'm unable to connect the dots.
My Login code happens to reside at ../api/Authentication/Login.js in the file structure. Is that going to matter to my test code, or can I simply reference something like .post('Login')? Either way, here's an overview of my Login.js file:
var auth = require('azure-mobile-apps/src/auth'),
bcrypt = require('bcrypt-nodejs');
module.exports = {
post: function (req, res, next) {
// Actual code removed
}
};
I have no idea how to construct the req, res, and next variables/parameters. When it comes to this point, an article I read by Michael Herman (link) seems to be closer to what I'm trying to do.
In that article, a test-server.js file is set up with contents like this:
var chai = require('chai');
var chaiHttp = require('chai-http');
var server = require('../server/app');
var should = chai.should();
chai.use(chaiHttp);
describe('Blobs', function() {
it('should list ALL blobs on /blobs GET', function(done) {
chai.request(server)
.get('/blobs')
.end(function(err, res){
res.should.have.status(200);
done();
});
});
});
This seems to be referencing /blobs because in ../server/models/blob.js, there is this line:
module.exports = mongoose.model('blobs', blobSchema);
That's what makes me think that maybe the following lines (in my Login.js) are doing something more structured behind the scenes:
module.exports = {
post:
Anyway, this is just the tip of the iceberg. My Azure Mobile App has environment variables and connection strings, etc. Is it possible for me to get all of that running on my local machine, or am I better off to implement my testing in Azure's portal somehow?
If I should do it locally, how can I get that set up?
If I should do it in Azure's portal, how do I begin there?

Related

Creating an API to wrap an... API?

This isn’t a specific issue question, but I’m trying to wrap my head around the concept of REST APIs and calling an API within your own API.
For example, if I develop an App called “BeesBees”, where users can buy bees, and I have a database of logins and passwords and obviously the bees, and how much each cost, I understand that I can used my own apps BeesBees API to get the list of bees (and if I make it open for other people, they can also use my GET /bees point to get, well, the bees)
But if I want to allow customers to buy the bees, and I don’t want to build a whole platform for doing so, so I integrate Stripe - could I have a POST /:users/charges/:priceOfBee API call that, in turn, called the Stripe API function somewhere somehow? For example, pointing to the URL of a Node.js project that will make the charge using Stripe’s Node.js SDK.
Or, in a case like this, would it be better to just implement the Stripe SDK for my device’s platform and make the charge using the device?
I have no code base so there’s nothing to pick apart, but I couldn’t think of anywhere else to ask, sorry y’all
You can certainly wrap APIs with other APIs, it's really just a form of composition, delegate to other services where it makes sense to do so.
Stripe integration might well be a good example of where it could make sense to follow this pattern. You certainly don't want to roll your own payment service.
Here's a trivial example of a local Express server making an API request:
const express = require("express");
const port = 3000;
const app = express();
const request = require('request');
app.get("/api/example", (req, res) => {
// Make external REST request here...
let options = {
url: 'https://httpbin.org/get',
qs: { parameter1: 42 },
json: true
}
request(options, (err, response, body) => {
if (err) {
res.status(500).send(err.message);
} else {
res.status(200).send(body);
}
});
});
var server = app.listen(3000, function () {
var host = server.address().address;
var port = server.address().port;
console.log('running at http://' + host + ':' + port)
});
console.log(`Serving at http://localhost:${port}`);

Testing for server in Koa

I am using Koa for web development in NodeJS, I have a server file, which does nothing but to start the server and initialise few middlewares. Following is the sample code
server.js
const Koa = require('koa');
var Router = require('koa-router');
var bodyParser = require('koa-bodyparser');
var app = new Koa();
var router = new Router();
app.use(bodyParser());
router.post('/abc', AbcController.abcAction);
router.post('/pqr', PqrController.pqrAction);
app.use(router.routes());
app.listen(3000);
When we run npm start the server will start on 3000 port and now I want to write unit test case for this file using mocha, chai and sinon.
One way is to create a test file lets say server_test.js and do something like the following(just an example):
var server = require(./server);
server.close();
For this we need to add the following lines to server.js
var server = app.listen(3000);
module.exports = server;
Is this a good practice to do? I think we should not expose server in this fashion?
As we don't have self created function here in this file, is testing really required?
Should we also exclude such files from sonarqube coverage?
Any other better suggestion is always welcome. Need your help guys. Thank you.
You can use chai-http for testing the endpoint
this is what I use for my project
const chai = require('chai');
const chaiHttp = require('chai-http');
const expect = chai.expect;
const app = require('../app');
describe('/GET roles', function () {
it('should return bla bla bla',
function (done) {
chai.request(app)
.get('/roles')
.end(function (err, res) {
expect(res.status).eql(200)
expect(res.body).to.have.property('message').eql('Get role list success');
expect(res.body).to.have.property('roles');
expect(err).to.be.null;
done();
});
}
);
});
There are primarily 2 ways through which you can actually handle rest cases.
One is to put your test cases along with your source code file. ( in your case it would be server.spec.js ). I personally prefer this way as it encourages code modularity and make your modules totally independent.
Another way is to create another directory, let say test, where you can put your entire test cases according to same directory structure as followed by the main application. This is really useful for applications where test cases are only considered while they are in development phase and then at time of production you can simply ignore sending these files.
Also, I usually prefer following the concepts of functional programming as it really helps to test each block of code independently.
Hope this helps

How would I test sending a route with mocha/chai/superagent in express?

it('sends login page if we\'re logged out at /', function (done) {
superagent.get('http://localhost:4000/').end(function(err, res){
if(err) {return done(err)}
expect(res).to.have.property('status', 200);
//how would i do something like this?
expect(res.viewRendered).to.be.equal('index.ejs')
done();
});
});
I'm new to testing and I hate it.. a lot. I'm trying to learn the basics and it's the most frustrating learning curve I've ever experienced. I've been looking up documentation for hours and still haven't been able to figure out how to check which route has been rendered
I would go about this another way: instead of relying on the output of the request, and match that up against a template (which can be quite difficult unless you add some sort of identifier to each template, which doesn't feel entirely right), you can take advantage of some internals of Express, and specifically on how it renders templates.
The Express documentation states the following (here):
Express-compliant template engines such as Pug export a function named __express(filePath, options, callback), which is called by the res.render() function to render the template code.
You are not using Pug, but EJS, but the same principle applies: the ejs module exports a function called __express which will be called with full path of the template that should be rendered. And that also happens to be what you want to test for!
So the question now becomes: "how can you test that ejs.__express() gets called with the proper template name?". Answer: you can spy on it.
My favorite module for this is Sinon, so the example below will use that. Sinon is great to spy on existing functions, or to make them do entirely different things if you want.
As an example, I will use the following, very simple, Express app:
// app.js
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.render('index.ejs', { foo : 'bar' });
});
module.exports = app;
We want to test if, when / is requested, the template index.ejs gets rendered.
Instead of using superagent, I'll be using supertest, which is meant for testing HTTP apps.
Here's the annotated Mocha test file:
// Import the Express app (from the file above), which we'll be testing.
const app = require('./app');
// Import some other requirements.
const expect = require('chai').expect;
const supertest = require('supertest');
const sinon = require('sinon');
// Import the EJS library, because we need it to spy on.
const ejs = require('ejs');
// Here's the actual test:
it('sends login page if we\'re logged out at /', function (done) {
// We want to spy on calls made to `ejs.__express`. We use Sinon to
// wrap that function with some magic, so we can check later on if
// it got called, and if so, if it got called with the correct
// template name.
var spy = sinon.spy(ejs, '__express');
// Use supertest to retrieve / and make sure that it returns a 200 status
// (so we don't have to check for that ourselves)
supertest(app)
.get('/')
.expect(200)
.end((err, res) => {
// Pass any errors to Mocha.
if (err) return done(err);
// Magic! See text below.
expect(spy.calledWithMatch(/\/index\.ejs$/)).to.be.true;
// Let Sinon restore the original `ejs.__express()` to its original state.
spy.restore();
// Tell Mocha that our test case is done.
done();
});
});
So what's this magic:
spy.calledWithMatch(/\/index\.ejs$/)
It means: "return true if the function that was being spied on (ejs.__express()) got called with a first argument that matches the regular expression \/index\.ejs$". Which is what you want to test for.
The reason I'm using a regular expression here is because I'm lazy. Because the first argument (filePath in the quote above) will contain the full path to the template file, it can be quite long. You can directly test for it if you want:
spy.calledWith(__dirname + '/views/index.ejs')
But that would break if the location of the template directory got changed. So, like I said, I'm lazy, and I'll use a regular expression match instead.
With tools like supertest, sinon and chai, testing can actually become fun (honest!). I have to agree that the learning curve is rather steep, but perhaps that an annotated example like this can help you get a better idea on what's possible and how to go about it.

Where do I put database connection information in a Node.js app?

Node.js is my first backend language and I am at the point where I am asking myself "where do I put the database connection information?".
There is a lot of good information regarding this issue. Unfortunately for me all the examples are in PHP. I get the ideas but I am not confident enough to replicate it in Node.js.
In PHP you would put the information in a config file outside the web root, and include it when you need database data.
How would you do this in Node.js? using the Express.js framework.
So far I have this:
var express = require('express'), app = express();
var mysql = require('mysql');
app.get('/', function(req,res) {
var connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'store'
});
var query = connection.query('SELECT * from customers where email = "deelo42#gmail.com"');
query.on('error', function(err) {
throw err;
});
query.on('fields', function(fields) {
console.log('this is fields');
});
query.on('result', function(row) {
var first = row.first_name;
var last = row.last_name;
res.render('index.jade', {
title: "My first name is " + first,
category: "My last name is " + last
});
});
});
app.listen(80, function() {
console.log('we are logged in');
});
As you can see I have a basic express application with 1 GET route. This route sets off the function to go to the database and pull out information based on an email address.
At the top of the GET route is the database connection information. Where do I put that? How do I call it? How do I keep it out of web root, and include it like PHP ? Can you please show me in a working example. Thanks!
I use the Express Middleware concept for same and that gives me nice flexibility to manage files.
I am writing a detailed answer, which includes how i am use the config params in app.js to connect to DB.
So my app structure looks something this:
How i connect to DB? (I am using MongoDB, mongoose is ORM, npm install mongoose)
var config = require('./config/config');
var mongoose = require("mongoose");
var connect = function(){
var options = {
server: {
socketOptions:{
keepAlive : 1
}
}
};
mongoose.connect(config.db,options);
};
connect();
under the config folder i also have 'env' folder, which stores the environment related configurations in separate files such as development.js, test.js, production.js
Now as the name suggests, development.js stores the configuration params related to my development environment and same applies to the case of test and production. Now if you wish you can have some more configuration setting such as 'staging' etc.
project-name/config/config.js
var path = require("path");
var extend = require("util")._extend;
var development = require("./env/development");
var test = require("./env/test");
var production = require("./env/production");
var defaults = {
root: path.normalize(__dirname + '/..')
};
module.exports = {
development: extend(development,defaults),
test: extend(test,defaults),
production: extend(production,defaults)
}[process.env.NODE_ENV || "development"]
project-name/config/env/test.js
module.exports = {
db: 'mongodb://localhost/mongoExpress_test'
};
Now you can make it even more descriptive by breaking the URL's into, username, password, port, database, hostname.
For For more details have a look at my repo, where you can find this implementation, in fact now in all of my projects i use the same configuration.
If you are more interested then have a look at Mean.js and Mean.io, they have some better ways to manage all such things. If you are beginner i would recommend to keep it simple and get things going, once you are comfortable, you can perform magic on your own. Cheers
I recommend the 12-factor app style http://12factor.net which keeps all of this in env vars. You never should have this kind of information hard-coded or in the app source-code / repo, so you can reuse it in different environments or even share it publicly without breaking security.
However, since there are lots of environment vars, I tend to keep them together in a single env.js like the previous responder wrote - although it is not in the source code repo - and then source it with https://www.npmjs.org/package/dotenv
An alternative is to do it manually and keep it in, e.g. ./env/dev.json and just require() the file.
Any of these works, the important point is to keep all configuration information separate from code.
I agree with the commenter, put it in a config file. There is no ultimate way, but nconf is also one of my favourites.
The important best practise is that you keep the config separate if you have a semi-public project, so your config file will not overwrite other developers.
config-sample.json (has to be renamed and is tracked with for example git)
config.json (not tracked / ignored by git)

How to Make a Call to Koa.js App Instance for Unit Tests

I don't know how I'd term this maybe 'static call to a koa router'? Does that seem like the right wordage here for what I'm really trying to accomplish if you were to talk about it technically?
Anyway, I'm using koa-router and I'm coding unit tests (not integration tests). So I do not want to invoke .listen() on my koa app because of that reason...it would create an http server which now makes my test an integration tests.
Instead in my test I simply want to make a straight call to the app object instance and call a route and be able to return no results and check that I returned no results in the response.
How can you do that? I can't find an example and I've tried all sorts of pseudo code attemps agains the koa app object.
If you want to test the function that koa-router routes to then just perform a unit test on that function and leave the routing out of it.
To me it sounds like you've got a file such as app.js and it contains all your code. What you can do is create a router.js file to put you route bindings and a services.js file where you can put your application logic.
So for example app.js might look like:
var koa = require("koa");
var app = module.exports = koa();
var router = require('./router.js');
app.use(router.unsecured.middleware());
app.listen(3000);
And router.js might look like:
var router = require("koa-router");
var service = require("./services.js");
var unsecured = module.exports.unsecured = new router();
unsecured.post('/account/signin', service.signinUser);
unsecured.post('/account/register', service.registerUser);
And services.js might look like:
module.exports.signinUser = function*(signinDetails) {
// contains your application signin logic
};
module.exports.registerUser = function*(registerDetails) {
// contains your application register logic
};
So in this manner you can individually test services.js. I don't see any value in individually testing router.js since it is so trivial. As #Dan Pantry shows you can test routing as part of an integration test using supertest.
Edit:
So this is a little experimental test I was playing around with to test that the routing is correct. I'm using mocha as the test runner and the code example I posted in my original code.
// standard library
var assert = require("assert");
// in app objects
var router = require('./router.js');
var service = require('./service.js');
describe("routing tests", function() {
it("test register routing, POST", function*(done) {
// arrange
var unsecured = router.unsecured;
var path = '/account/register';
var httpMethod = 'POST';
var expected = service.register.toString();
var actual;
// act
for (var i = 0; i < unsecured.stack.length; i++)
{
var pathMatch = unsecured.stack[i].path === path;
var methodMatch = unsecured.stack[i].methods.indexOf(httpMethod) >= 0;
if (pathMatch && methodMatch)
{
actual = unsecured.stack[i].middleware.toString();
break;
}
}
// assert
try {
assert.equal(expected, actual);
done();
} catch(err) {
done(err);
}
});
});
There is probably a neater way of doing this (and a more modular way for testing multiple paths) but as I said this is just a basic example to verify the routing is calling the correct service. What I'm doing is delving into the koa-router object to verify what path is bound to what service code depending on the HTTP method (e.g. POST, GET, etc).
If you have your routing and your services in modules this test completely avoids dealing with the main koa app. Although technically this test spans multiple units (the routing and the service code) so it would technically be an integration test but it does mean you don't go near app.listen() which is what you didn't want to call in your tests.

Resources