1 | [![NPM](https://img.shields.io/npm/v/@salesforce/core.svg)](https://www.npmjs.com/package/@salesforce/core)
|
2 | [![CircleCI](https://circleci.com/gh/forcedotcom/sfdx-core.svg?style=svg&circle-token=2377ca31221869e9d13448313620486da80e595f)](https://circleci.com/gh/forcedotcom/sfdx-core)
|
3 |
|
4 | # Description
|
5 |
|
6 | The @salesforce/core library provides client-side management of Salesforce DX projects, org authentication, connections to Salesforce APIs, and other utilities. Much of the core functionality that powers the Salesforcedx plug-ins comes from this library. You can use this functionality in your plug-ins, too.
|
7 |
|
8 | # Usage
|
9 |
|
10 | See the [API documentation](https://forcedotcom.github.io/sfdx-core/).
|
11 |
|
12 | ## Contributing
|
13 |
|
14 | If you are interested in contributing, please take a look at the [CONTRIBUTING](https://github.com/forcedotcom/sfdx-core/blob/develop/CONTRIBUTING.md) guide.
|
15 |
|
16 | # Related Docs and Repositories
|
17 |
|
18 | - [@salesforce/command](https://github.com/forcedotcom/cli-packages/tree/master/packages/command) - Contains base Salesforce CLI command, `SfdxCommand`.
|
19 | - [@salesforce/plugin-generator](https://github.com/forcedotcom/sfdx-plugin-generate) - The generator plug-in for building plug-ins for Salesforce CLI.
|
20 |
|
21 | # Using TestSetup
|
22 |
|
23 | The Salesforce DX Core Library provides a unit testing utility to help with mocking and sand-boxing core components. This feature allows unit tests to execute without needing to make API calls to salesforce.com.
|
24 |
|
25 | ## Mocking AuthInfo
|
26 |
|
27 | Here you can mock authorization for a Salesforce scratch org.
|
28 |
|
29 | ```typescript
|
30 | import { strictEqual } from 'assert';
|
31 | import { MockTestOrgData, testSetup } from '@salesforce/core/lib/testSetup';
|
32 | import { AuthInfo } from '@salesforce/core';
|
33 |
|
34 | const $$ = testSetup();
|
35 |
|
36 | describe('Mocking Auth data', () => {
|
37 | it('example', async () => {
|
38 | const testData = new MockTestOrgData();
|
39 | $$.setConfigStubContents('AuthInfoConfig', {
|
40 | contents: await testData.getConfig()
|
41 | });
|
42 | const auth: AuthInfo = await AuthInfo.create({ username: testData.username });
|
43 | strictEqual(auth.getUsername(), testData.username);
|
44 | });
|
45 | });
|
46 | ```
|
47 |
|
48 | After having a valid AuthInfo object you can then create fake connections to a Salesforce.com scratch org. This allows for writing tests that can validate result responses for SOQL queries and REST endpoints.
|
49 |
|
50 | ```typescript
|
51 | import { AuthInfo, Connection, SfdxError } from '@salesforce/core';
|
52 | import { MockTestOrgData, testSetup } from '@salesforce/core/lib/testSetup';
|
53 | import { AnyJson, ensureJsonMap, JsonMap } from '@salesforce/ts-types';
|
54 | import { ensureString } from '@salesforce/ts-types';
|
55 | import { deepStrictEqual } from 'assert';
|
56 | import { QueryResult } from 'jsforce';
|
57 |
|
58 | const $$ = testSetup();
|
59 |
|
60 | describe('Mocking a force server call', () => {
|
61 | it('example', async () => {
|
62 | const records: AnyJson = { records: ['123456', '234567'] };
|
63 | const testData = new MockTestOrgData();
|
64 | $$.setConfigStubContents('AuthInfoConfig', {
|
65 | contents: await testData.getConfig()
|
66 | });
|
67 | $$.fakeConnectionRequest = (request: AnyJson): Promise<AnyJson> => {
|
68 | const _request: JsonMap = ensureJsonMap(request);
|
69 | if (request && ensureString(_request.url).includes('Account')) {
|
70 | return Promise.resolve(records);
|
71 | } else {
|
72 | return Promise.reject(new SfdxError(`Unexpected request: ${_request.url}`));
|
73 | }
|
74 | };
|
75 | const connection: Connection = await Connection.create({
|
76 | authInfo: await AuthInfo.create({ username: testData.username })
|
77 | });
|
78 | const result: QueryResult<{}> = await connection.query('select Id From Account');
|
79 | deepStrictEqual(result, records);
|
80 | });
|
81 | });
|
82 | ```
|
83 |
|
84 | ## Using the Built-in Sinon Sandboxes
|
85 |
|
86 | sfdx-core uses Sinon as its underlying mocking system. If you're unfamiliar with Sinon and it's sandboxing concept you can find more information here:
|
87 | https://sinonjs.org/
|
88 | Sinon `stub`s and `spy`s must be cleaned up after test invocations. To ease the use of Sinon with sfdx core we've exposed our sandbox in TestSetup. After adding your own `stub`s and/or `spy`s they will automatically be cleaned up after each test using mocha's afterEach method.
|
89 |
|
90 | ```typescript
|
91 | import { strictEqual } from 'assert';
|
92 |
|
93 | import { testSetup } from '@salesforce/core/lib/testSetup';
|
94 | import * as os from 'os';
|
95 |
|
96 | const $$ = testSetup();
|
97 |
|
98 | describe('Using the built in Sinon sandbox.', () => {
|
99 | it('example', async () => {
|
100 | const unsupportedOS = 'LEO';
|
101 | $$.SANDBOX.stub(os, 'platform').returns(unsupportedOS);
|
102 | strictEqual(os.platform(), unsupportedOS);
|
103 | });
|
104 | });
|
105 | ```
|
106 |
|
107 | ## Testing Expected Failures
|
108 |
|
109 | It's important to have negative tests that ensure proper error handling. With `shouldThrow` it's easy to test for expected async rejections.
|
110 |
|
111 | ```typescript
|
112 | import { SfdxError } from '@salesforce/core';
|
113 | import { shouldThrow } from '@salesforce/core/lib/testSetup';
|
114 | import { strictEqual } from 'assert';
|
115 |
|
116 | class TestObject {
|
117 | public static async method() {
|
118 | throw new SfdxError('Error', 'ExpectedError');
|
119 | }
|
120 | }
|
121 |
|
122 | describe('Testing for expected errors', () => {
|
123 | it('example', async () => {
|
124 | try {
|
125 | await shouldThrow(TestObject.method());
|
126 | } catch (e) {
|
127 | strictEqual(e.name, 'ExpectedError');
|
128 | }
|
129 | });
|
130 | });
|
131 | ```
|
132 |
|
133 | ## Testing Log Lines
|
134 |
|
135 | It's also useful to check expected values and content from log lines. TestSetup configures the sfdx-core logger to use an in memory LogLine storage structure. These can be easily accessed from tests.
|
136 |
|
137 | ```typescript
|
138 | import { Logger, LogLine } from '@salesforce/core';
|
139 | import { testSetup } from '@salesforce/core/lib/testSetup';
|
140 | import { strictEqual } from 'assert';
|
141 |
|
142 | const $$ = testSetup();
|
143 |
|
144 | const TEST_STRING = 'foo was here';
|
145 |
|
146 | class TestObject {
|
147 | constructor(private logger: Logger) {
|
148 | this.logger = logger.child('TestObject');
|
149 | }
|
150 |
|
151 | public method() {
|
152 | this.logger.error(TEST_STRING);
|
153 | }
|
154 | }
|
155 |
|
156 | describe('Testing log lines', () => {
|
157 | it('example', async () => {
|
158 | const obj: TestObject = new TestObject($$.TEST_LOGGER);
|
159 | obj.method();
|
160 | const records: LogLine[] = $$.TEST_LOGGER.getBufferedRecords();
|
161 | strictEqual(records.length, 1);
|
162 | strictEqual(records[0].msg, TEST_STRING);
|
163 | });
|
164 | });
|
165 | ```
|