├── .npmrc ├── .travis.yml ├── .whitesource ├── .editorconfig ├── src ├── __tests__ │ ├── sample_sls_project │ │ ├── serverless.yml │ │ └── handler.js │ └── serverless_environment.test.js ├── lambda_wrapper.js └── index.js ├── .eslintrc ├── LICENSE.txt ├── .gitignore ├── package.json └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | registry = https://registry.npmjs.org 2 | access = public 3 | scope = "@fireeye" 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" 4 | - "10" 5 | - "11" 6 | cache: npm 7 | env: 8 | - NPM_TOKEN="" 9 | -------------------------------------------------------------------------------- /.whitesource: -------------------------------------------------------------------------------- 1 | { 2 | "scanSettings": { 3 | "configMode": "AUTO", 4 | "configExternalURL": "", 5 | "projectToken" : "" 6 | }, 7 | "checkRunSettings": { 8 | "vulnerableCheckRunConclusionLevel": "failure" 9 | }, 10 | "issueSettings": { 11 | "minSeverityLevel": "LOW" 12 | } 13 | } -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file. 2 | [*] 3 | indent_style = space 4 | indent_size = 2 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | insert_final_newline = true 8 | end_of_line = lf 9 | max_line_length = 120 10 | 11 | [**/*.js] 12 | quote_type = single 13 | -------------------------------------------------------------------------------- /src/__tests__/sample_sls_project/serverless.yml: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file. 2 | service: jest-test-suite 3 | provider: 4 | name: aws 5 | runtime: nodejs8.10 6 | region: us-east-1 7 | environment: 8 | STAGE: prod-stage-test 9 | functions: 10 | hello: 11 | handler: handler.hello 12 | environment: 13 | HELLO: "world ${self:provider.region}" 14 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "env": { 4 | "node": true, 5 | "es6": true, 6 | "jest": true, 7 | "jest/globals": true 8 | }, 9 | "rules": { 10 | "no-console": "off", 11 | "max-len": ["error", {"code": 100, "ignoreUrls": true}], 12 | "comma-dangle": ["error", "always-multiline"], 13 | "no-param-reassign": "off" 14 | }, 15 | "extends": [ 16 | "airbnb-base", 17 | "plugin:jest/recommended", 18 | "prettier" 19 | ], 20 | "plugins": [ 21 | "jest" 22 | ], 23 | "globals": { 24 | "ServerlessWrapper": false 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/__tests__/sample_sls_project/handler.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file. */ 2 | 3 | module.exports.hello = (event, context, callback) => { 4 | const response = { 5 | statusCode: 200, 6 | body: JSON.stringify({ 7 | message: 'Go Serverless v1.0! Your function executed successfully!', 8 | stage: process.env.STAGE, 9 | input: event, 10 | }), 11 | }; 12 | 13 | if (process.env.STAGE !== 'prod-stage-test' || process.env.HELLO !== 'world us-east-1') { 14 | // trigger error with output 15 | callback('Environmental variables failed'); 16 | throw new Error('Environmental variables failed'); 17 | } 18 | 19 | return callback(null, response); 20 | }; 21 | -------------------------------------------------------------------------------- /src/lambda_wrapper.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file. */ 2 | 3 | const path = require('path'); 4 | 5 | const lambdaWrapper = jest.requireActual('lambda-wrapper'); 6 | 7 | global.LambdaWrapper = { 8 | async getWrapper(functionName) { 9 | const { rootDir, serverless } = ServerlessWrapper; 10 | 11 | const func = serverless.service.getFunction(functionName); 12 | const [handlerFile, handler] = func.handler.split('.'); 13 | 14 | const mod = jest.requireActual(path.join(rootDir, handlerFile)); 15 | 16 | const wrapped = lambdaWrapper.wrap(mod, { 17 | handler, 18 | }); 19 | // Make sure this methods env vars take priority 20 | ServerlessWrapper.setEnv(functionName); 21 | 22 | return wrapped; 23 | }, 24 | }; 25 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-present, FireEye, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file. 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | 7 | # Runtime data 8 | pids 9 | *.pid 10 | *.seed 11 | *.pid.lock 12 | 13 | # Test data 14 | test-results.xml 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (http://nodejs.org/api/addons.html) 35 | build/Release 36 | build/ 37 | 38 | # Dependency directories 39 | node_modules/ 40 | jspm_packages/ 41 | 42 | # Typescript v1 declaration files 43 | typings/ 44 | 45 | # Optional npm cache directory 46 | .npm 47 | 48 | # Optional eslint cache 49 | .eslintcache 50 | 51 | # Optional REPL history 52 | .node_repl_history 53 | 54 | # Output of 'npm pack' 55 | *.tgz 56 | 57 | # serverless files 58 | .serverless 59 | .webpack 60 | 61 | # VSCode 62 | .vs/ 63 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jest-environment-serverless", 3 | "version": "0.2.4", 4 | "author": "FireEye, Inc.", 5 | "repository": { 6 | "type": "git", 7 | "url": "https://github.com/fireeye/jest-environment-serverless" 8 | }, 9 | "bugs": { 10 | "url": "https://github.com/fireeye/jest-environment-serverless/issues" 11 | }, 12 | "license": "SEE LICENSE IN LICENSE.txt", 13 | "main": "src/index.js", 14 | "keywords": [ 15 | "jest", 16 | "serverless" 17 | ], 18 | "engines": { 19 | "node": ">=8.0.0" 20 | }, 21 | "scripts": { 22 | "test": "npx jest" 23 | }, 24 | "dependencies": { 25 | "lambda-wrapper": "^0.3.0" 26 | }, 27 | "devDependencies": { 28 | "eslint": "^6.0.1", 29 | "eslint-config-airbnb-base": "^13.2.0", 30 | "eslint-config-prettier": "^6.0.0", 31 | "eslint-plugin-import": "^2.18.0", 32 | "eslint-plugin-jest": "^22.7.1", 33 | "jest": "^24.8.0", 34 | "jest-cli": "^24.8.0", 35 | "jest-config": "^24.8.0", 36 | "jest-runtime": "^24.8.0", 37 | "jest-util": "^24.8.0", 38 | "serverless": "^1.41.1" 39 | }, 40 | "peerDependencies": { 41 | "jest-environment-node": "23.x || 24.x", 42 | "serverless": ">=1.46" 43 | }, 44 | "jest": { 45 | "collectCoverage": true, 46 | "coverageReporters": [ 47 | "text" 48 | ], 49 | "silent": true, 50 | "testEnvironment": "node", 51 | "testMatch": [ 52 | "**/__tests__/**/?(*.)+(spec|test).js?(x)", 53 | "**/?(*.)+(spec|test).js?(x)" 54 | ], 55 | "verbose": true 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file. */ 2 | 3 | // Help resolve peer dependencies 4 | const path = require('path'); 5 | 6 | module.paths.unshift(path.join(process.cwd(), 'node_modules')); 7 | 8 | const NodeEnvironment = require('jest-environment-node'); 9 | const Serverless = require('serverless'); 10 | 11 | class ServerlessWrapper extends NodeEnvironment { 12 | constructor(config) { 13 | super(config); 14 | 15 | const wrapperPath = path.join(__dirname, 'lambda_wrapper.js'); 16 | const ignoreCoveragePaths = ['\\.serverless', '\\.serverless_plugins']; 17 | 18 | // Add the LambdaWrapper to the front of the `setupFiles` list 19 | if (!Array.isArray(config.setupFiles)) { 20 | config.setupFiles = []; 21 | } 22 | if (!config.setupFiles.includes(wrapperPath)) { 23 | config.setupFiles.unshift(wrapperPath); 24 | } 25 | 26 | // Add the LambdaWrapper to the front of the `setupFiles` list 27 | if (!Array.isArray(config.coveragePathIgnorePatterns)) { 28 | config.coveragePathIgnorePatterns = ['node_modules']; 29 | } 30 | const pathsToAdd = ignoreCoveragePaths.filter( 31 | item => !config.coveragePathIgnorePatterns.includes(item) 32 | ); 33 | if (pathsToAdd.length) { 34 | config.coveragePathIgnorePatterns.push(...pathsToAdd); 35 | } 36 | 37 | this.global.ServerlessWrapper = { 38 | Serverless, 39 | rootDir: config.cwd, 40 | }; 41 | 42 | this.global.process.env.SERVERLESS_TEST_ROOT = true; 43 | 44 | const serverless = new Serverless({ 45 | interactive: false, 46 | servicePath: config.cwd, 47 | }); 48 | this.global.ServerlessWrapper.serverless = serverless; 49 | this.global.ServerlessWrapper.getEnv = this.getEnv; 50 | this.global.ServerlessWrapper.setEnv = this.setEnv; 51 | } 52 | 53 | async setup() { 54 | await super.setup(); 55 | 56 | const { serverless } = this.global.ServerlessWrapper; 57 | 58 | await serverless.init(); 59 | await serverless.variables.populateService({}); 60 | 61 | serverless.service.mergeArrays(); 62 | serverless.service.setFunctionNames({}); 63 | serverless.service.validate(); 64 | 65 | // Populate all env vars 66 | const serviceVars = serverless.service.provider.environment || {}; 67 | const functionVars = serverless.service.getAllFunctions().map(this.getEnv.bind(this)); 68 | const vars = Object.assign({}, serviceVars, ...functionVars); 69 | Object.assign(this.global.process.env, vars); 70 | } 71 | 72 | getEnv(funcName) { 73 | const useGlobal = !(this.global && this.global.ServerlessWrapper); 74 | let instance; 75 | 76 | if (useGlobal) { 77 | instance = this.serverless; 78 | } else { 79 | instance = this.global.ServerlessWrapper.serverless; 80 | } 81 | 82 | return instance.service.functions[funcName] 83 | ? instance.service.functions[funcName].environment 84 | : {}; 85 | } 86 | 87 | setEnv(funcName) { 88 | const useGlobal = !(this.global && this.global.ServerlessWrapper); 89 | const vars = this.getEnv(funcName); 90 | 91 | let env; 92 | 93 | if (useGlobal) { 94 | env = Object.assign(process.env, vars); 95 | } else { 96 | env = Object.assign(this.global.process.env, vars); 97 | } 98 | 99 | return env; 100 | } 101 | 102 | async tearDown() { 103 | delete this.global.ServerlessWrapper; 104 | } 105 | } 106 | 107 | module.exports = ServerlessWrapper; 108 | -------------------------------------------------------------------------------- /src/__tests__/serverless_environment.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file. */ 2 | 3 | const { readConfig } = require('jest-config'); 4 | const Runtime = require('jest-runtime'); 5 | const { Console } = require('jest-util'); 6 | 7 | const path = jest.requireActual('path'); 8 | const ServerlessEnvironment = jest.requireActual('../'); 9 | const Serverless = jest.requireActual('serverless'); 10 | 11 | describe('ServerlessEnvironment', () => { 12 | it('uses a copy of the process object', () => { 13 | const env1 = new ServerlessEnvironment({}); 14 | const env2 = new ServerlessEnvironment({}); 15 | 16 | expect(env1.global.process).not.toBe(env2.global.process); 17 | }); 18 | 19 | it('exposes process.on', () => { 20 | const env1 = new ServerlessEnvironment({}); 21 | 22 | expect(env1.global.process.on).not.toBe(null); 23 | }); 24 | 25 | it('exposes global.global', () => { 26 | const env1 = new ServerlessEnvironment({}); 27 | 28 | expect(env1.global.global).toBe(env1.global); 29 | }); 30 | 31 | it('should configure setTimeout/setInterval to use the node api', () => { 32 | const env1 = new ServerlessEnvironment({}); 33 | 34 | env1.fakeTimers.useFakeTimers(); 35 | 36 | const timer1 = env1.global.setTimeout(() => {}, 0); 37 | const timer2 = env1.global.setInterval(() => {}, 0); 38 | 39 | [timer1, timer2].forEach(timer => { 40 | expect(timer.id).toBeDefined(); 41 | expect(typeof timer.ref).toBe('function'); 42 | expect(typeof timer.unref).toBe('function'); 43 | }); 44 | }); 45 | 46 | it('exposes global.ServerlessWrapper and default properties', () => { 47 | const config = {}; 48 | const env1 = new ServerlessEnvironment(config); 49 | 50 | // Verify updated config properties 51 | ['setupFiles', 'coveragePathIgnorePatterns'].forEach(field => { 52 | expect(config).toHaveProperty(field); 53 | expect(Array.isArray(config[field])).toBeTruthy(); 54 | }); 55 | 56 | expect(env1.global.ServerlessWrapper).toBeDefined(); 57 | // Verify global context properties 58 | ['Serverless', 'rootDir', 'serverless'].forEach(field => 59 | expect(env1.global.ServerlessWrapper).toHaveProperty(field) 60 | ); 61 | expect(env1.global.ServerlessWrapper.Serverless).toBe(Serverless); 62 | expect(env1.global.ServerlessWrapper.serverless).toBeInstanceOf(Serverless); 63 | }); 64 | 65 | it('sets global.process.env.SERVERLESS_TEST_ROOT', () => { 66 | const env1 = new ServerlessEnvironment({}); 67 | 68 | expect(env1.global).toHaveProperty('process.env.SERVERLESS_TEST_ROOT', 'true'); 69 | }); 70 | 71 | it('only adds the LambdaWrapper to the setupFiles array once', () => { 72 | const config = { 73 | setupFiles: [], 74 | }; 75 | 76 | // Simulate multiple Jest runtimes executing 77 | /* eslint-disable no-new */ 78 | new ServerlessEnvironment(config); 79 | new ServerlessEnvironment(config); 80 | new ServerlessEnvironment(config); 81 | /* eslint-disable no-new */ 82 | 83 | expect(config.setupFiles).toEqual([path.join(__dirname, '../', 'lambda_wrapper.js')]); 84 | }); 85 | 86 | describe('setEnv', () => { 87 | let slsEnv; 88 | 89 | beforeEach(() => { 90 | slsEnv = new ServerlessEnvironment({ 91 | cwd: path.join(__dirname, 'sample_sls_project'), 92 | }); 93 | }); 94 | 95 | it('sets the environment variables globally', async () => { 96 | const functionEnv = slsEnv.setEnv('hello'); 97 | expect(functionEnv).not.toHaveProperty('HELLO'); 98 | }); 99 | }); 100 | 101 | describe('ServerlessWrapper', () => { 102 | let slsEnv; 103 | let LambdaWrapper; 104 | 105 | beforeAll(async () => { 106 | const { globalConfig, projectConfig } = readConfig([], path.join(__dirname, '../')); 107 | const config = Object.assign({}, projectConfig, { 108 | cwd: path.join(__dirname, 'sample_sls_project'), 109 | }); 110 | 111 | slsEnv = new ServerlessEnvironment(config); 112 | 113 | const context = await Runtime.createContext(config, { 114 | console: new Console(process.stdout, process.stdout), 115 | maxWorkers: globalConfig.maxWorkers, 116 | watch: false, 117 | watchman: globalConfig.watchman, 118 | }); 119 | 120 | await slsEnv.setup(); 121 | 122 | new Runtime(config, slsEnv, context.resolver, context.hasteFS); 123 | 124 | // eslint-disable-next-line prefer-destructuring 125 | LambdaWrapper = slsEnv.global.LambdaWrapper; 126 | }); 127 | 128 | afterAll(async () => { 129 | await slsEnv.tearDown(); 130 | }); 131 | 132 | it('wraps and retrieves a function from serverless.yml', async () => { 133 | const wrapped = await LambdaWrapper.getWrapper('hello'); 134 | const response = await wrapped.run(); 135 | expect(response).toBeDefined(); 136 | expect(response).toHaveProperty('statusCode', 200); 137 | }); 138 | 139 | describe('setEnv', () => { 140 | it('uses the supplied Serverless instance if provided', async () => { 141 | slsEnv.global.ServerlessWrapper.serverless.service.functions.hello.environment.testEnvVar = 142 | 'some value'; 143 | 144 | await LambdaWrapper.getWrapper('hello'); 145 | 146 | expect(process.env).toHaveProperty('testEnvVar', 'some value'); 147 | }); 148 | }); 149 | }); 150 | }); 151 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # jest-environment-serverless 2 | 3 | Run your [Serverless](https://serverless.com) tests using Jest, quickly and easily! This project exposes a [Lambda Wrapper](https://github.com/nordcloud/lambda-wrapper) to your tests in order to make it effortless and easy to test your lambdas. 4 | 5 | Installing is as easy as: 6 | 7 | ```shell 8 | npm install serverless jest jest-environment-serverless 9 | ``` 10 | 11 | ## Usage 12 | 13 | Update your Jest configuration to set the [testEnvironment](https://jestjs.io/docs/en/configuration#testenvironment-string) to `jest-environment-serverless`: 14 | 15 | _package.json_ 16 | ```json 17 | { 18 | "name": "my-project", 19 | "scripts": { 20 | "test": "jest" 21 | }, 22 | "jest": { 23 | "testEnvironment": "jest-environment-serverless" 24 | } 25 | } 26 | ``` 27 | 28 | Use Serverless in your tests: 29 | 30 | ```javascript 31 | describe('Hello Lambda', () => { 32 | let wrapper; 33 | 34 | beforeAll(async () => { 35 | wrapper = await LambdaWrapper.getWrapper('hello'); 36 | }); 37 | 38 | it('says hello', async () => { 39 | const event = { name: 'Bob' }; 40 | const response = await wrapper.run(event); 41 | expect(response).toHaveProperty('message', 'Hi Bob!'); 42 | }); 43 | }); 44 | ``` 45 | 46 | Run your tests: 47 | 48 | ```shell 49 | npm test 50 | ``` 51 | 52 | ## API 53 | 54 | ### `global.LambdaWrapper` 55 | 56 | This global variable provides convenient access to the [lambda-wrapper](https://github.com/nordcloud/lambda-wrapper) module in order to simulate lambda executions for the given events and contexts, fully initialized with your `Serverless` configuration, providing a more accurate and thorough testing scenario than attempting to invoke and test your lambdas directly. 57 | 58 | #### `getWrapper()` 59 | 60 | When provided with a valid `Serverless` function name, `getWrapper` will return a configured, ready-to-run [lambda wrapper](https://github.com/nordcloud/lambda-wrapper). 61 | 62 | With a simple `serverless.yml` 63 | ```yaml 64 | service: jest-test-suite 65 | provider: 66 | name: aws 67 | runtime: nodejs8.10 68 | region: us-east-1 69 | environment: 70 | STAGE: prod-stage-test 71 | functions: 72 | hello: 73 | handler: handler.hello 74 | environment: 75 | HELLO: "world ${self:provider.region}" 76 | ``` 77 | 78 | You can obtain a reference to the `hello` lambda in order to simulate various conditions and assert the expected behaviors: 79 | 80 | ```javascript 81 | describe('Hello Lambda', () => { 82 | let wrapper; 83 | 84 | beforeAll(async () => { 85 | wrapper = await LambdaWrapper.getWrapper('hello'); 86 | }); 87 | 88 | it('says hello', async () => { 89 | const event = { name: 'Bob' }; 90 | const response = await wrapper.run(event); 91 | expect(response).toHaveProperty('message', 'Hi Bob!'); 92 | }); 93 | }); 94 | ``` 95 | 96 | ### `global.ServerlessWrapper` 97 | 98 | This global variable provides access to a number of properties that can be safely ignored in nearly all but the most challenging test scenarios. These are primarily used by the [LambdaWrapper](#global.LambdaWrapper) in order to discover the service and configuration for a given lambda during testing. 99 | 100 | #### `Serverless` 101 | 102 | This provides direct access to the `Serverless` class. 103 | 104 | #### `rootDir` 105 | 106 | Exposes the root directory used by `Serverless` to load the configuration and plugins from. By default, this value is set to the `cwd`. 107 | 108 | #### `serverless` 109 | 110 | This provides direct access to the initialized `Serverless` instance in case it is needed to help assert or verify anything during testing. With this, you can access: 111 | - processed configuration 112 | - loaded services 113 | - loaded plugins 114 | - variables 115 | 116 | You can also dynamically modify the configuration or services to assist while testing, without needing to manage multiple test projects or copying files to temporary directories. 117 | 118 | #### `getEnv()` 119 | 120 | Exposes the environment variables for the function defined in your Serverless Configuration. For example: 121 | 122 | With a simple `serverless.yml` 123 | ```yaml 124 | service: jest-test-suite 125 | provider: 126 | name: aws 127 | runtime: nodejs8.10 128 | region: us-east-1 129 | environment: 130 | STAGE: prod-stage-test 131 | functions: 132 | hello: 133 | handler: handler.hello 134 | environment: 135 | HELLO: "world ${self:provider.region}" 136 | ``` 137 | 138 | Calling `getEnv` would return: 139 | ```javascript 140 | // This is the name of the lambda declared in the "functions" block in the 141 | // serverless.yml 142 | const envVars = ServerlessWrapper.getEnv('hello'); 143 | assert.deepEqual(envVars, { HELLO: 'world us-east-1' }); 144 | ``` 145 | 146 | #### `setEnv()` 147 | 148 | Updates `process.env` with the environment variables for the function defined in your Serverless Configuration. For example: 149 | 150 | With a simple `serverless.yml` 151 | ```yaml 152 | service: jest-test-suite 153 | provider: 154 | name: aws 155 | runtime: nodejs8.10 156 | region: us-east-1 157 | environment: 158 | STAGE: prod-stage-test 159 | functions: 160 | hello: 161 | handler: handler.hello 162 | environment: 163 | HELLO: "world ${self:provider.region}" 164 | goodbye: 165 | handler: handler.goodbye 166 | environment: 167 | HELLO: "cruel world" 168 | GOODBYE: "world ${self:provider.region}" 169 | ``` 170 | 171 | Calling `setEnv` would return: 172 | ```javascript 173 | // All serverless env vars are initially loaded, but lambda env vars are 174 | // not prioritized and may override one another 175 | assert.deepEqual(process.env, { 176 | ... 177 | HELLO: 'cruel world', 178 | GOODBYE: 'world us-east-1', 179 | ... 180 | }); 181 | // This is the name of the lambda declared in the "functions" block in the 182 | // serverless.yml 183 | const envVars = ServerlessWrapper.setEnv('hello'); 184 | 185 | // The "hello" lambda env vars have been loaded and take priority over all 186 | // others 187 | assert.deepEqual(process.env, { 188 | ... 189 | HELLO: 'world us-east-1', 190 | GOODBYE: 'world us-east-1', 191 | ... 192 | }); 193 | ``` 194 | 195 | _Copyright (C) 2019 FireEye, Inc. All Rights Reserved. See LICENSE file._ 196 | --------------------------------------------------------------------------------