Suitecloud Unit Testing allows you to use unit testing with Jest for your SDF projects.
- Provides a default configuration to run unit tests with Jest in SDF projects.
- Supports unit testing for SuiteScript 2.X files.
- Provides SuiteScript 2.X stubs.
💡 For SuiteCloud Unit Testing 1.X.X, only the N/record module is supported.
- Allows you to create custom stubs for SuiteScript 2.X or custom modules.
- Supports code coverage capabilities through Jest.
- Node.js version 12.14.0 LTS or greater
- An SDF project
⚠ SuiteCloud Unit Testing is installed as a
devDependency
.
To get started with SuiteCloud Unit Testing, do the following:
- Inside of your SDF project folder, create a
src
folder. - Move your project files inside of the
src
folder. - To initialize the NPM package, from the root of your SDF project folder, run
npm init
.
💡 A
package.json
file is created in your SDF project folder.
- In your
package.json
file, add the following code:
{
"scripts": {
"test": "jest"
}
}
- From the root of your SDF project folder, run the followig command:
npm install --save-dev @oracle/suitecloud-unit-testing jest
- Create a
__tests__
folder, inside of the root of your SDF project folder. - Create a
sample-test.js
file, inside of the__tests__
folder, with the following content:
describe('Basic jest test with simple assert', () => {
it('should assert stings are equal', () => {
const a = 'foobar';
const b = 'foobar';
expect(a).toMatch(b);
});
});
- From the root of your SDF project folder, run
npm test
to run your test. You should see an output similar to following:
PASS __tests__/sample-test.js
Basic jest test with simple assert
√ should assert stings are equal (2ms)
💡 If you want to run tests with coverage, from the root of your SDF project folder, run
npm test --coverage
.
You successfully ran your first test for an SDF project!
➡ If you use SuiteCloud CLI for Node.js, you can install SuiteCloud Unit Testing when running the project:create
command by following the questions prompted.
To properly run your tests against the SuiteScript 2.X files of your SDF project, create a jest.config.js
file inside of the root of your SDF project folder.
The jest.config.js
file must follow a specific structure. Depending on your SDF project type, check one of the following examples:
- For Account Customization Projects:
const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src', //or your SDF project folder
projectType: SuiteCloudJestConfiguration.ProjectType.ACP,
});
- For SuiteApps:
const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src', //or your SDF project folder
projectType: SuiteCloudJestConfiguration.ProjectType.SUITEAPP,
});
Here you can find two examples on how to use SuiteCloud Unit Testing with an SDF project.
The first example covers testing for the N/record module, which is fully mocked in SuiteCloud Unit Testing. Whereas the second example covers the testing of a module that is not mocked in SuiteCloud Unit Testing, by using a custom stub.
💡 You can manually mock any module that is still not supported in SuiteCloud Unit Testing.
This example follows the structure presented below:
myAccountCustomizationProject
├── __tests__
│ └── sample-test.js
├── node_modules
├── src
│ ├── AccountConfiguration
│ ├── FileCabinet
│ ├── SuiteScripts
│ └── Suitelet.js
│ ├── Objects
│ ├── Translations
│ ├── deploy.xml
│ └── manifest.xml
├── jest.config.js
├── suitecloud.config.js
├── package-lock.json
├── package.json
└── project.json
See below the content of the SuiteCloud Unit Testing files:
jest.config.js
file
const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src',
projectType: SuiteCloudJestConfiguration.ProjectType.ACP,
});
Suitelet.js
file
/**
* @NApiVersion 2.x
* @NScriptType Suitelet
* @NModuleScope SameAccount
*/
define(["N/record"], function(record) {
return {
onRequest: function(context) {
if (context.request.method === 'GET') {
const salesOrderId = context.request.parameters.salesOrderId;
let salesOrderRecord = record.load({id: salesOrderId});
salesOrderRecord.setValue({fieldId: 'memo', value: "foobar"});
salesOrderRecord.save({enableSourcing: false});
}
}
};
});
Suitelet.test.js
file
import Suitelet from "SuiteScripts/Suitelet";
import record from "N/record";
import Record from "N/record/instance";
jest.mock("N/record");
jest.mock("N/record/instance");
beforeEach(() => {
jest.clearAllMocks();
});
describe("Suitelet Test", () => {
it("Sales Order memo field has been updated", () => {
// given
const context = {
request: {
method: 'GET',
parameters: {
salesOrderId: 1352
}
}
};
record.load.mockReturnValue(Record);
Record.save.mockReturnValue(1352);
// when
Suitelet.onRequest(context);
// then
expect(record.load).toHaveBeenCalledWith({id: 1352});
expect(Record.setValue).toHaveBeenCalledWith({fieldId: 'memo', value: 'foobar'});
expect(Record.save).toHaveBeenCalledWith({enableSourcing: false});
});
});
To read a comprehensive description of this example, visit NetSuite's Help Center.
This example follows the structure presented below:
myAccountCustomizationProject
├── customStubs
│ └── http.js
├── __tests__
│ └── http.test.js
├── node_modules
├── src
│ ├── AccountConfiguration
│ ├── FileCabinet
│ ├── SuiteScripts
│ ├── Templates
│ ├── Web Site Hosting Files
│ ├── Objects
│ ├── Translations
│ ├── deploy.xml
│ └── manifest.xml
├── jest.config.js
├── suitecloud.config.js
├── package-lock.json
├── package.json
└── project.json
See below the content of the SuiteCloud Unit Testing files:
jest.config.js
file
const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src',
projectType: SuiteCloudJestConfiguration.ProjectType.ACP,
customStubs: [
{
module: "N/http",
path: "<rootDir>/customStubs/http.js"
}
]
});
http.js
file: This is the stub file. It partially mocks NetSuite's N/http module.
💡 The JSDoc annotations are copied from NetSuite's N/http module, but are not required to run SuiteCloud unit testing.
define([], function() {
/**
* @namespace http
*/
var http = function() {};
/**
* Send a HTTP GET request and return a reponse from a server.
*
* @governance 10 units
* @restriction Server SuiteScript only
*
* @param {Object} options
* @param {string} options.url the HTTP URL being requested
* @param {Object} options.headers (optional) The HTTP headers
* @return {ClientResponse}
*
* @throws {SuiteScriptError} SSS_MISSING_REQD_ARGUMENT if a required argument is missing
* @throws {SuiteScriptError} SSS_INVALID_URL if an incorrect protocol is used (ex: http in the HTTPS module)
*
* @since 2015.2
*/
http.prototype.get = function(options) {};
/**
* @exports N/http
* @namespace http
*/
return new http();
});
http.test.js
file
import http from 'N/http';
jest.mock('N/http');
beforeEach(() => {
jest.clearAllMocks();
});
describe('Sample test with user defined http module stub', () => {
it('should call http get method', () => {
// given
const clientResponseMock = {
code: 200,
body: {
data: 'foobar'
}
// more properties and functions here if needed
};
http.get.mockReturnValue(clientResponseMock);
const options = {
url: 'https://netsuite.com'
};
// when
const clientResponse = http.get(options);
// then
expect(http.get).toHaveBeenCalledWith(options);
expect(clientResponse).toMatchObject({
code: 200,
body: {
data: 'foobar'
}
});
});
});
To read a comprehensive description of this example, visit NetSuite's Help Center.
Suitecloud Unit Testing is an open source project. Pull Requests are currently not being accepted. See CONTRIBUTING for details.
Copyright (c) 2020 Oracle and/or its affiliates The Universal Permissive License (UPL), Version 1.0.