Skip to content

Commit

Permalink
BREAKING CHANGE: rename unitTestUtils and alter its behavior
Browse files Browse the repository at this point in the history
the module is moved into a new class, `SdkUnitTestUtilities`, that does rely on `jest` or any dev dependencies. users must import the class, instantiate a new instance, and pass jest's `expect` method to the constructor. all methods are the same but must be accessed through the class.
  • Loading branch information
dpopp07 committed Jul 17, 2020
1 parent 80f2376 commit 5ac3950
Show file tree
Hide file tree
Showing 7 changed files with 156 additions and 197 deletions.
2 changes: 1 addition & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ export * from './lib/helper';
export { default as qs } from './lib/querystring';
export { default as contentType } from './lib/content-type';
export * from './lib/stream-to-promise';
export * from './test/utils';
export { SdkUnitTestUtilities } from './lib/sdk-test-helpers';
126 changes: 126 additions & 0 deletions lib/sdk-test-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* Copyright 2019 IBM Corp. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* istanbul ignore file */

/** Configuration options for the testing utilities. */
export interface Options {
/** The Jest expect function to use */
expect: Function;
}

/**
* This class provides a set of helper methods used to reduce code duplication in the generated unit tests
* for the SDKs that depend on this core package. Note that these methods are not used by the tests for this
* package - they are meant to be exported and made available to dependent libraries.
*/
export class SdkUnitTestUtilities {
private expect: Function;

/**
* Create a new BasicAuthenticator instance. !!!!!!!
*
* @param {object} options Configuration options for basic authentication. !!!!!!!!!!
* @param {string} options.username The username portion of basic authentication. !!!!!!!!!!
* @param {string} options.password The password portion of basic authentication. !!!!!!!!!!
* @throws {Error} The configuration options are not valid. !!!!!!!!!!
*/
constructor(options: Options) {
// injecting the dependency on the "expect" method from `jest` so that
// this module does not rely on "devDependencies"
this.expect = options.expect;
}

/**
* Takes the request options constructed by the SDK and checks that the `url` and `method` properties
* were set to their correct values.
*
* @param {Object} options - the options object put together by the SDK, retrieved from the createRequest mock
* @param {String} url - The URL path of the service endpoint, from the paths section of the API definition
* @param {String} string - The HTTP method for the request, from the API definition
* @returns {void}
*/
public checkUrlAndMethod(options, url: string, method: any) {
this.expect(options.url).toEqual(url);
this.expect(options.method).toEqual(method);
};

/**
* Takes the mock object for the `createRequest` method, extracts the headers that were sent with the call,
* and checks for the expected values for `Accept` and `Content-Type`. This to verify that the SDK sets
* the correct values in the code.
*
* @param {Object} createRequestMock - the jest mock object for the `createRequest` method in the `RequestWrapper` class
* @param {String} accept - the expected value for the `Accept` header
* @param {String} contentType - the expected value for the `Content-Type` header
* @returns {void}
*/
public checkMediaHeaders(createRequestMock, accept: string, contentType: string) {
const headers = createRequestMock.mock.calls[0][0].defaultOptions.headers;
this.expect(headers.Accept).toEqual(accept);
this.expect(headers['Content-Type']).toEqual(contentType);
};

/**
* Takes the mock object for the `createRequest` method, extracts the headers that were sent with the call,
* and checks for the expected value for a user-defined header. This is verify that the SDK accepts header
* parameters and sends them as headers in the request.
*
* @param {Object} createRequestMock - the jest mock object for the `createRequest` method in the `RequestWrapper` class
* @param {String} userHeaderName - the name of the header passed by the user, e.g. `Contained-Content-Type`
* @param {String} userHeaderValue - the expected value for the header passed by the user
* @returns {void}
*/
public checkUserHeader(createRequestMock, userHeaderName: string, userHeaderValue: string) {
const headers = createRequestMock.mock.calls[0][0].defaultOptions.headers;
this.expect(headers[userHeaderName]).toEqual(userHeaderValue);
};

/**
* This method simply ensures that the method executed without any issues by extracting
* the argument from the mock object for the `createRequest` method and verifying that it is an object.
*
* @param {Object} createRequestMock - the jest mock object for the `createRequest` method in the `RequestWrapper` class
* @returns {void}
*/
public checkForSuccessfulExecution(createRequestMock) {
const sdkParams = createRequestMock.mock.calls[0][0];
this.expect(typeof sdkParams).toEqual('object');
};

/**
* This method extracts the `options` property from the object passed into `createRequest`. This property is
* an object containing all of the SDK method-specific information (like `path` and `body`) used to build a request.
* This method is just a convenience method for the unit tests to be able to make assertions on the items in the request.
*
* @param {Object} createRequestMock - the jest mock object for the `createRequest` method in the `RequestWrapper` class
* @returns {Object}
*/
public getOptions(createRequestMock) {
return createRequestMock.mock.calls[0][0].options;
};

/**
* This method simply ensures that the SDK methods return Promises by checking for
* the `then` function - common way to assess whether or not an object is a Promise.
*
* @param {Promise<any>} sdkPromise - the Promise returned by an SDK method
* @returns {void}
*/
public expectToBePromise(sdkPromise) {
this.expect(typeof sdkPromise.then).toBe('function');
};
}
73 changes: 20 additions & 53 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@
"mime-types": "~2.1.18",
"object.omit": "~3.0.0",
"object.pick": "~1.3.0",
"semver": "^6.2.0",
"ts-jest": "^25.5.1"
"semver": "^6.2.0"
},
"browser": {
"./auth/utils/read-credentials-file": "./auth/utils/read-credentials-file.browser"
Expand Down
18 changes: 8 additions & 10 deletions test/unit/export-unit-test-utils.test.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
'use strict';

const { unitTestUtils } = require('../../dist');
const { SdkUnitTestUtilities } = require('../../dist');

describe('Unit Test Utils', () => {
it('should be defined', () => {
expect(unitTestUtils).toBeDefined();
});
const utils = new SdkUnitTestUtilities({ expect });

it('should have function checkUrlAndMethod', () => {
expect(unitTestUtils.checkUrlAndMethod).toBeDefined();
expect(utils.checkUrlAndMethod).toBeDefined();
});

it('should have function checkMediaHeaders', () => {
expect(unitTestUtils.checkMediaHeaders).toBeDefined();
expect(utils.checkMediaHeaders).toBeDefined();
});

it('should have function checkUserHeader', () => {
expect(unitTestUtils.checkUserHeader).toBeDefined();
expect(utils.checkUserHeader).toBeDefined();
});

it('should have function checkForSuccessfulExecution', () => {
expect(unitTestUtils.checkForSuccessfulExecution).toBeDefined();
expect(utils.checkForSuccessfulExecution).toBeDefined();
});

it('should have function getOptions', () => {
expect(unitTestUtils.getOptions).toBeDefined();
expect(utils.getOptions).toBeDefined();
});

it('should have function expectToBePromise', () => {
expect(unitTestUtils.expectToBePromise).toBeDefined();
expect(utils.expectToBePromise).toBeDefined();
});
});
Loading

0 comments on commit 5ac3950

Please sign in to comment.