Test your Suitescripts before deploying to NetSuite.
nsmockup is a tool to create NetSuite Suite Scripts unit tests.
You can test your code before deploy it to your NetSuite account. Do you develop NetSuite Suite Scripts? Well, then you know how complicated is to test your code! You need to upload it, configure your script, start the debbuger and, maybe, you can test that!
This further complicates in larger projects, where you reuse your code in several Suite Scripts.
To improve our development process SuitePlus idealized the nsmockup, so developers can:
- Simulate NetSuite environment locally.
- Create automated tests for your projects in a controlled environment.
- node.js 4+
npm install nsmockup --save-dev
Param | Type | Description |
---|---|---|
opt.current.company | string |
Define company of the current NetSuite user. Default NSMOCKUPVxxx . |
opt.current.user.id | number |
Define the ID of the current NetSuite user. Default -4 for anonymous. Default null . |
opt.current.user.type | string |
Define the type of the current NetSuite user, see options: "employee" , "customer" , "vendor" or "partner" . Default "entity" |
opt.general.currency | string |
Set currency. Default $ . |
opt.general.dateFormat | string |
Global Preferences: dateformat , default "MM/DD/YYYY" . |
opt.general.numberFormat.decimal | string |
Set decimal format. Default "." . |
opt.general.numberFormat.precision | string |
Set number format precision. Default 2 . |
opt.general.numberFormat.thousand | string |
Set thousand format. Default "," . |
opt.general.timeFormat | string |
Global Preferences: timeFormat , default "hh:mm A" . |
opt.general.lang | string |
Global Preferences: lang , default "en" . |
opt.metadata | [string] |
List of Records Types Metadata, generate that with ns-export. |
opt.records | [string] |
Data list of Records, generate that with ns-export. |
opt.server | boolean |
Set true and start server on port 3030 . Used for Suitelet and RESTlet simulations. |
cb | function |
Callback Function. |
var opt = {
records: {
"customrecord_my-record": __dirname + '/data/customrecord_my-record.json'
},
metadata: [
__dirname + '/meta/metaData-customrecord_my-record.json'
],
server: true
};
nsmockup.init(opt, function(err) {
if (err) console.log('ERROR', err);
else console.log('start Netsuite API simulation')
});
Param | Type | Description |
---|---|---|
cfg.id | string |
Custom ID of Suitelet. |
cfg.name | string |
Name of Suitelet. |
cfg.function | string |
Defines the function that should be called from the selected script file. |
cfg.files | [string] |
Path to JavaScripts files that contains your implementation. |
cfg.params | object |
Default parameters to run your implementation. |
cb | function |
Callback Function sent ctx (type: object ) - the context and exec (type: function ) invoke your code in side the context. |
nsmockup.createSuitelet({
id: 'my_suitelet',
name: 'My Suitelet',
function: 'MySuitelet.main',
files: [
__dirname + '/lib/my-suitelet.js'
]
}, (ctx, exec) => {
// verify if function 'MySuitelet' was loaded
if (!ctx.MySuitelet) throw 'not found MySuitelet'
// invoke my RESTlet
let url = nlapiResolveURL('SUTELET', 'my_suitelet'),
res = nlapiRequestURL(url + 'message=hi');
if (res.getBody() === 'hello') {
console.log('Finish Suitelet');
}
});
Param | Type | Description |
---|---|---|
cfg.id | string |
Custom ID of RESTlet. |
cfg.name | string |
Name of RESTlet. |
cfg.functions.get | string |
Sets the script function that should execute as the HTTP GET method. |
cfg.functions.post | string |
Sets the script function that should execute as the HTTP POST method. |
cfg.functions.put | string |
Sets the script function that should execute as the HTTP PUT method. |
cfg.functions.delete | string |
Sets the script function that should execute as the HTTP DELETE method. |
cfg.files | [string] |
Path to JavaScripts files that contains your implementation. |
cfg.params | object |
Default parameters to run your implementation. |
cb | function |
Callback Function sent ctx (type: object ) - the context and exec (type: function ) invoke your code in side the context. |
nsmockup.createRESTlet({
id: 'my_restlet',
name: 'My RESTlet',
functions: {
get: 'MyRestlet.get',
post: 'MyRestlet.post'
},
files: [
__drname + '/lib/my-restlet.js'
]
}, (ctx, exec) => {
// verify if function 'MyRestlet' was loaded
if (!ctx.MyRestlet) throw 'not found MyRestlet'
// invoke my RESTlet
let url = nlapiResolveURL('RESTLET', 'my_restlet'),
res = nlapiRequestURL(url, {message: 'live?'}, null, 'POST');
if (res.getBody() === 'yeap!') {
console.log('Finish RESTlet');
}
});
Param | Type | Description |
---|---|---|
cfg.id | string |
Custom ID of Schedule. |
cfg.name | string |
Name of Schedule. |
cfg.function | string |
Defines the function that should be called from the selected script file. |
cfg.files | [string] |
Path to JavaScripts files that contains your implementation. |
cfg.params | object |
Default parameters to run your implementation. |
cfg.exec | boolean |
If true , nsmockup will run de ScheduleScript before the callback function was called. |
cb | function |
Callback Function sent ctx (type: object ) - the context and exec (type: function ) invoke your code in side the context. |
nsmockup.createSchedule({
id: 'my_schedule',
name: 'My Schedule',
function: 'MySchedule.main',
files: [
__dirname + '/lib/my-schedule.js'
],
exec: false
}, (ctx, exec) => {
// verify if function 'MySchedule' was loaded
if (!ctx.MySchedule) throw 'not found MySchedule'
// execute 'MyOtherFunc.getJapo'
// you can execute any function present in file '/lib/my-schedule.js'
let japo = exec('MyOtherFunc.getJapo');
if (japo.verifyFinishSchedule()) {
console.log('Finished Schedule');
}
});
Param | Type | Description |
---|---|---|
cfg.id | string |
Custom ID of User Event. |
cfg.name | string |
Name of User Event. |
cfg.functions.beforeLoad | string |
Sets the script function that should execute whenever a read operation on a record occurs. |
cfg.functions.beforeSubmit | string |
Sets the function that should execute before the associated record is submitted |
cfg.functions.afterSubmit | string |
Sets the function that should execute after the associated record is submitted. |
cfg.files | [string] |
Path to JavaScripts files that contains your implementation. |
cfg.params | object |
Default parameters to run your implementation. |
cfg.records | [string] |
Apply this event in this records. |
cb | function |
Callback Function sent ctx (type: object ) - the context and exec (type: function ) invoke your code in side the context. |
nsmockup.createUserEvent({
id: 'my_user-event',
name: 'My User Event',
functions: {
beforeLoad: 'MyUserEvent.beforeLoad',
beforeSubmit: 'MyUserEvent.beforeSubmit',
afterSubmit: 'MyUserEvent.afterSubmit',
},
files: [
__dirname + '/lib/my-user-event.js'
],
record: 'customer'
}, (ctx, exec) => {
// verify if function 'MyUserEvent' was loaded
if (!ctx.MyUserEvent) throw 'not found MySchedule'
var should = require('should')
let record = nlapiLoadRecord('customer', 219);
record.setFieldValue('name', 'Muito Legal');
nlapiSubmitRecord(record);
let context = ctx.nlapiGetContext();
should(context).be.ok();
let beforeLoadType = context.getSessionObject('before-load-type');
should(beforeLoadType).be.equal('view');
let beforeSubmitType = context.getSessionObject('before-submit-type');
should(beforeSubmitType).be.equal('edit');
let afterSubmitType = context.getSessionObject('after-submit-type');
should(afterSubmitType).be.equal('edit');
});
Param | Type | Description |
---|---|---|
cb | function |
Callback Function. |
nsmockup.destroy(function(err) {
if (err) console.log('ERROR', err);
else console.log('finish Netsuite API simulation')
});
'use strict';
var nsmockup = require('nsmockup');
describe('<Unit Test - Netsuite API Simulation>', function () {
before(function (done) {
// map record types
let metadata = [
__dirname + '/record/meta/recordType-metaData-codeg.json',
__dirname + '/record/meta/recordType-metaData-codeg_ids.json'
],
records = {
'customrecord_codeg': __dirname + '/record/data/recordType-codeg.json',
'customrecord_codeg_ids': __dirname + '/record/data/recordType-codeg_ids.json'
};
// start database simulation
nsmockup.init({records, metadata, server: true}, done);
});
it('simple load lib and execute function', function (done) {
nsmockup.createReslet({
name: 'my_restlet',
functions: {
get: 'MyRestlet.get',
post: 'MyRestlet.post'
},
files: [
__dirname + '/lib/my-restlet.js'
]
}, (ctx, exec) => {
// verify if function 'MyRestlet' was loaded
if (!ctx.MyRestlet) throw 'not found MyRestlet'
// invoke my RESTlet
let url = nlapiResolveURL('RESTLET', 'my_restlet'),
res = nlapiRequestURL(url, {message: 'live?'}, null, 'POST');
if (res && res.getBody() === 'yeap!') {
console.log('Finish RESTlet');
} else {
throw new Error('invalid result');
}
});
});
after(function (done) {
nsmockup.destroy(done);
});
});