Cloud Code Functions
Cloud Code Unit Tests
22min
how to create a unit test through their cloud code functions introduction this section will allow you to check the operation and testing of your functions locally using the library parse server test runner prerequisites to complete this tutorial, you will need a local environment with node js installed to apply unit tests you can follow the official nodejs tutorial to successfully install node js at your terminal an app created at back4app follow the create new app tutorial to learn how to create an app at back4app back4app command line configured with the project follow the setting up cloud code tutorial to learn how to set up cloud code for a project first off, we need to talk about unit test! when developers start writing a function with different intentions in mind, a major point evident in the software community is the application of imaginary scenarios for the created code to be tested it is necessary to perform the unit tests procedure as it allows you to test the code in parts, which ensures that your main code remains intact and uncompromised and now, how about a simple practical example? let’s assume that you need to write a function to show in a complete sentence, the name from the worker, the position and company we’ll need to write the function to get the following input items company position worker name steps to complete the simple test in your terminal, initially, we’ll create a directory and configure your test app (package json) first, using the following command $ mkdir unit test sample && cd unit test sample $ npm init hint using the npm init npm init command, you’ll be able to create the package json file it only covers the most common items and tries to guess sensible defaults because of this, we’ll make available the dependencies necessary for the code to work the result from “package json” will be something like the example below { "name" "yourfoldername", "version" "1 0 0", "description" "just a unit test with using a simple function ", "main" "index js", "scripts" { "test" "echo \\"error no test specified\\" && exit 1" }, "repository" { "type" "git", "url" "" }, "author" "your name", "license" "isc", "bugs" { "url" "{url}/issues" }, "homepage" "" } now, let’s create the file (index js) using the command below /unit test sample$ touch index js we will now insert the code below into the previously created file, and the function will insert an example that can demonstrate this test with the code 1 // index js 2 module exports = function(name, position, company) { 3 let sentence = "hi, " + name + "! you are " + position + " in " + company + " company "; 4 return sentence; 5 }; in nodejs, the module encapsulates the related code into a single unit of code, and when you’re using module exports , it increases encapsulated code that can be utilized in other files let’s test 0/ finally, you can work with your terminal /unit test sample$ node \> var moduleback4app = require(' /index js'); undefined \> moduleback4app("jonathan", "developer", "back4app") hi, jonathan! you are developer in back4app company hint using the require() require() function, you’re able to import and export modules, and in the case above, we are using this function to require a file inside an application and using parse, can i test my function? of course, as a test parameter, we will create a backend to control the information of a company’s employees let’s structure the classes as parse user (reference for employees) username, email, password (required) we recommend you to have a detailed look at the parse server guide in order to get some more information about user properties infoemployee position department workshift userid (pointer) 1 understand our final structure let’s get started! we will use the parse server javascript guide as a parameter for the development of our functions firstly, after completing the setup using the command line interface (see prereqs https //www back4app com/docs/cloud code functions/unit tests#content prerequisites ), we’ll understand how it will work with the final structure from the files ├──back4appproject │ ├── cloud │ │ ├── functions js │ │ ├── main js │ ├── public │ ├── package json │ ├── index js │ ├── node modules │ ├── src │ │ ├── jasmine js notice when you upload the files to your cloud code, the command line interface (see prereqs ) will ignore the other files and upload only the ones that are in the public and cloud folder 2 writing our function after configuring the environment for the command line interface, we’ll write the function to build the process to register the employee and save the additional information by refactoring the code, at the main js file, we’ll import these functions into main, like 1 //in 1cloud/main js 2 3 var cloudfunctions = require(" /functions"); 4 5 / it's necessary to insert the parse instance in our code, 6 because at local context not is referenced / 7 8 parse cloud define("registeruser", cloudfunctions registeruser(parse)); 9 10 parse cloud beforesave("infoemployee", infoemployee infoemployee(parse)); the idea is to decouple the functions from the cloud interface so we may test them without sending http requests inefficiently this will make a lot of sense as we create the test suite parse server 3 x 1 //in cloud/functions js 2 3 module exports registeruser = function(parse){ 4 return async(request) =>{ 5 let params = request params; //parameters received 6 let infoemployee = parse object extend("infoemployee"); //store information 7 8 let usercreated = new parse user({ 9 "email" params email, 10 "username" params username, 11 "password" params password 12 }) 13 14 //save relation 15 try { 16 let result = await usercreated save(); 17 18 let information = new infoemployee({ 19 "position" params position, 20 "department" params department, 21 "workshift" params shift, 22 "user" result 23 }); 24 25 return information save(); 26 } catch (e) { 27 return e message; 28 } 29 } 30 } 31 32 module exports infoemployee = function(parse){ 33 return async (request) =>{ 34 let req = request object; 35 36 if (!req get("position") || !req get("department") || !req get("workshift")) { 37 throw new error("missing params! the required parameters are position, department workshift"); 38 } else { 39 return; 40 } 41 } 42 } parse server 2 x 1 //in cloud/functions js 2 3 module exports registeruser = function(parse){ 4 return function (request, response){ 5 var params = request params; //parameters received 6 7 var infoemployee = parse object extend("infoemployee"); //store information 8 9 var usercreated = new parse user({ 10 "email" params email, 11 "username" params username, 12 "password" params password 13 }) 14 15 //save relation 16 usercreated save() then((updateduser) => { 17 var information = new infoemployee({ 18 "position" params position, 19 "department" params department, 20 "workshift" params shift, 21 "user" updateduser 22 }); 23 return information save(); 24 }) then((info) => response success(info)) 25 catch((e) => { 26 response error(e message); 27 }) 28 } 29 } 30 31 module exports infoemployee = function(parse){ 32 return function (request, response){ 33 var req = request object; 34 35 if (!req get("position") || !req get("department") || !req get("workshift")) { 36 response error("missing params! the required parameters are position, department workshift"); 37 } else { 38 response success(); 39 } 40 } 41 } 3 setting up the environment to test the above code! for our test suite, we will be using jasmine , a highly popular javascript testing framework however, our code so far is completely agnostic of our tests, so you may use whatever framework or platform you prefer install the development dependencies let’s install jasmine globally and use, with the commands below /back4appproject$ sudo npm install g jasmine /back4appproject$ jasmine randomized with seed 48094 started no specs found finished in 0 002 seconds incomplete no specs found 4 configuring parse server test runner in the folder with our methods implemented in the project cloud folder in back4app, we will create new files on our project on node js that will configure this interaction /back4appprojectsrc$ touch index js /back4appproject$ mkdir src && cd src /back4appproject/src$ touch jasmine js now, we will configure the files created above with the codes shown below index js 1 const promise = require('bluebird'); 2 const express = require('express'); 3 const http = require('http'); 4 const {mongoclient} = require('mongodb'); 5 const {parseserver} = require('parse server'); 6 7 const mongodbrunnerstart = require('mongodb runner/mocha/before') bind({ 8 timeout() { 9 }, 10 slow() { 11 }, 12 }); 13 const mongodbrunnerstop = require('mongodb runner/mocha/after'); 14 15 const startdb = () => ( 16 new promise((done, reject) => { 17 done fail = reject; 18 mongodbrunnerstart(done); 19 }) 20 ); 21 22 const stopdb = () => ( 23 new promise((done, reject) => { 24 done fail = reject; 25 mongodbrunnerstop(done); 26 }) 27 ); 28 29 const connectdb = (databaseuri) => new promise((resolve, reject) => { 30 mongoclient connect(databaseuri, (err, db) => { 31 if (err) { 32 reject(err); 33 } else { 34 resolve(db); 35 } 36 }); 37 }); 38 39 let parseserverstate = {}; 40 41 const dropdb = () => { 42 const {mongoconnection} = parseserverstate; 43 return mongoconnection dropdatabaseasync(); 44 }; 45 46 / 47 starts the parseserver idropdatabaseasyncnstance 48 @param {object} parseserveroptions used for creating the `parseserver` 49 @return {promise} runner state 50 / 51 function startparseserver(parseserveroptions = {}) { 52 const mongodbport = process env mongodb port || 27017; 53 const { 54 databasename = 'parse test', 55 databaseuri = 'mongodb //localhost ${mongodbport}/${databasename}', 56 masterkey = 'test', 57 javascriptkey = 'test', 58 appid = 'test', 59 60 port = 30001, 61 mountpath = '/1', 62 serverurl = 'http //localhost ${port}${mountpath}', 63 } = parseserveroptions; 64 65 return startdb() 66 then(() => connectdb(databaseuri)) 67 then((mongoconnection) => { 68 parseserveroptions = object assign({ 69 masterkey, javascriptkey, appid, 70 serverurl, 71 databaseuri, 72 silent process env verbose !== '1', 73 }, parseserveroptions); 74 const app = express(); 75 const parseserver = new parseserver(parseserveroptions); 76 77 app use(mountpath, parseserver); 78 79 const httpserver = http createserver(app); 80 81 promise promisifyall(httpserver); 82 promise promisifyall(mongoconnection); 83 84 return httpserver listenasync(port) 85 then(() => object assign(parseserverstate, { 86 parseserver, 87 httpserver, 88 mongoconnection, 89 expressapp app, 90 parseserveroptions, 91 })); 92 }); 93 } 94 95 / 96 stops the parseserver instance 97 @return {promise} 98 / 99 function stopparseserver() { 100 const {httpserver} = parseserverstate; 101 return httpserver closeasync() 102 then(stopdb) 103 then(() => parseserverstate = {}); 104 } 105 106 module exports = { 107 dropdb, 108 startparseserver, 109 stopparseserver, 110 parseserverstate, 111 }; jasmine js 1 const { startparseserver, stopparseserver, dropdb } = require('parse server test runner'); 2 3 describe('registeruser', () => { 4 beforeall((done) => { 5 const appid = 'test'; 6 const masterkey = 'test'; 7 const javascriptkey = 'test'; 8 9 startparseserver({ appid, masterkey, javascriptkey }) 10 then(() => { 11 parse initialize(appid, masterkey, javascriptkey); 12 parse serverurl = 'http //localhost 30001/1'; 13 }) 14 then(done) catch(done fail); 15 }, 300 60 2); 16 17 afterall((done) => { 18 stopparseserver() 19 then(done) catch(done fail); 20 }); 21 22 beforeeach((done) => { 23 dropdb() 24 then(done) catch(done fail); 25 }); 26 27 it('should work', (done) => { 28 const q = new parse query(' user') 29 q limit(5) 30 find({ usemasterkey true }) 31 then(console log) 32 then(done) catch(done fail); 33 }); 34 }); the last step is to configure the package json, using the command $ npm init $ npm init in the root directory (the file below is just an example with the modules required) 1 { 2 "name" "back4approject", 3 "version" "1 0 0", 4 "description" "back4app guide using for reference the parse server test runner", 5 "main" "index js", 6 "engines" { 7 "node" ">=6" 8 }, 9 "repository" { 10 "type" "", 11 "url" "" 12 }, 13 "keywords" \[ 14 "parse", 15 "parse server", 16 "testing", 17 "tests" 18 ], 19 "author" "", 20 "license" "isc", 21 "dependencies" { 22 "bluebird" "^3 5 0", 23 "express" "latest", 24 "mongodb" "^2 2 30", 25 "mongodb runner" "^3 5 0", 26 "parse" "^1 10 0", 27 "parse server" "^2 5 3", 28 "parse server test runner" "^1 0 0" 29 } 30 } and now, you’ll check that we approach the structure described in these previous https //www back4app com/docs/cloud code functions/unit tests#content structure steps ) 5 returning to the terminal we’ll start to configure the local testing, for this we’ll follow the command below to the code for set up programmatically for testing purposes /back4appproject$ # in the same directory from package json /back4appproject$ npm install after the successful installation, you’re able to check your unit test locally with the command described and receive the result, such as /back4appproject$ jasmine src/jasmine js randomized with seed 79055 started ✔ downloaded mongodb 3 6 5 \[] 1 spec, 0 failures finished in 19 983 seconds randomized with seed 79055 (jasmine random=true seed=79055) wonderful, it’s ready! with the guide described above, you’re able to work with the parse server test runner and your functions developed for the cloud code to back4app