<p align="left"><a href="#"><img width="250" src="resources/netsuite_logo_simplified.png"></a></p>
npm install @oracle/suitecloud-unit-testingproject:create command by following the questions prompted. This way, your project is initialized with SuiteCloud Unit Testing, and all the dependencies are being taken care of.
devDependency.
src folder.
src folder.
npm init.
package.json file is created in your SuiteCloud project folder.
package.json file, add the following code:
json
{
"scripts": {
"test": "jest"
}
}
`
5. From the root of your SuiteCloud project folder, run the followig command:
`
npm install --save-dev @oracle/suitecloud-unit-testing jest
`
6. Create a __tests__ folder, inside of the root of your SuiteCloud project folder.
7. Create a sample-test.js file, inside of the __tests__ folder, with the following content:
`javascript
describe('Basic jest test with simple assert', () => {
it('should assert stings are equal', () => {
const a = 'foobar';
const b = 'foobar';
expect(a).toMatch(b);
});
});
`
8. From the root of your SuiteCloud project folder, run npm test
to run your test. You should see an output similar to the following:
`
PASS __tests__/sample-test.js
Basic jest test with simple assert
√ should assert stings are equal (2ms)
`
You successfully ran your first test for a SuiteCloud project!
Additional Configuration
To properly run your tests against the SuiteScript 2.x files of your SuiteCloud project, create a jest.config.js file inside of the root of your SuiteCloud project folder.
The jest.config.js file must follow a specific structure. Depending on your SuiteCloud project type, check one of the following examples:
- For Account Customization Projects:
`javascript
const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src', //or your SuiteCloud project folder
projectType: SuiteCloudJestConfiguration.ProjectType.ACP,
});
`
- For SuiteApps:
`javascript
const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src', //or your SuiteCloud project folder
projectType: SuiteCloudJestConfiguration.ProjectType.SUITEAPP,
});
`
SuiteCloud Unit Testing Examples
Here you can find two examples on how to use SuiteCloud Unit Testing with a SuiteCloud 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.
$3
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
`javascript
const SuiteCloudJestConfiguration = require("@oracle/suitecloud-unit-testing/jest-configuration/SuiteCloudJestConfiguration");
module.exports = SuiteCloudJestConfiguration.build({
projectFolder: 'src',
projectType: SuiteCloudJestConfiguration.ProjectType.ACP,
});
`
- Suitelet.js file
`javascript
/**
* @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
`javascript
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});
});
});
`
$3
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
`javascript
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: "/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.
`javascript
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
`javascript
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'
}
});
});
});
``