UNPKG

@oracle/suitecloud-unit-testing

Version:

<p align="left"><a href="#"><img width="250" src="resources/netsuite_logo_simplified.png"></a></p>

329 lines (274 loc) ā€¢ 10.9 kB
<p align="left"><a href="#"><img width="250" src="resources/netsuite_logo_simplified.png"></a></p> # SuiteCloud Unit Testing <p> <a href="https://www.npmjs.com/package/@oracle/suitecloud-unit-testing"> <img src="https://img.shields.io/npm/dm/@oracle/suitecloud-unit-testing.svg" alt="npm-unit-testing"/> <img src="https://img.shields.io/npm/v/@oracle/suitecloud-unit-testing.svg" alt="npm-unit-testing"/> </a> </p> Suitecloud Unit Testing allows you to use unit testing with [Jest](https://jestjs.io/) for your SuiteCloud projects. ## Features - Provides a default configuration to run unit tests with Jest in SuiteCloud projects. - Supports unit testing for SuiteScript 2.x files. - Provides stubs for all SuiteScript 2.x modules. - Allows you to create custom stubs for any module used in SuiteScript 2.x files. For more information about the available SuitScript 2.x modules, see [SuiteScript 2.x Modules](https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/chapter_4220488571.html). For more information about all the mockable stubs, see the CORE_STUBS list in [SuiteCloudJestConfiguration.js](./jest-configuration/SuiteCloudJestConfiguration.js). ## Prerequisites - Node.js version 22 LTS - Having a SuiteCloud project ## Getting Started 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. This way, your project is initialized with SuiteCloud Unit Testing, and all the dependencies are being taken care of. > āš  SuiteCloud Unit Testing is installed as a `devDependency`. However, if you want to configure SuiteCloud Unit Testing manually, do the following: 1. Inside of your SuiteCloud project folder, create a `src` folder. 2. Move your project files inside of the `src` folder. 3. To initialize the NPM package, from the root of your SuiteCloud project folder, run `npm init`. >šŸ’” A `package.json` file is created in your SuiteCloud project folder. 4. In your `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. ### N/record Module Example 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}); }); }); ``` ### Custom Stub Example 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: "<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. ```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' } }); }); }); ``` ## Contributing Suitecloud Unit Testing is an open source project. Pull requests are currently not being accepted. See [Contributing](/CONTRIBUTING.md) for details. ## [License](/LICENSE.txt) Copyright (c) 2023, 2024, 2025 Oracle and/or its affiliates The Universal Permissive License (UPL), Version 1.0.