Skip to content
This repository was archived by the owner on Oct 25, 2021. It is now read-only.

Commit 0adfdbc

Browse files
author
erichendrickson
authored
Backended (mkdecisiondev#14)
* Updated to include first backend articles * Added reference * Update credentials-setup.md * Update credentials-setup.md * Changed titles of articles * Updated some info in document * Added basic Lambda tutorial * Updated chapters in README * Updated intro to AWS cloud * Update introduction-to-lambda.md * Added API Gateway chapter * 3. Advanced Topics ii. How to Pass a File Through API Gateway take 2 (mkdecisiondev#4) * added How to Pass a File Through API Gateway in markdown format * Update pass-file-through-API-gateway.md * Update pass-file-through-API-gateway.md * Lambda transfer buckets (mkdecisiondev#3) * set up directory for guide and images, link to guide in readme * add info about creating buckets * add completed doc for using Lambda to transfer files between buckets * remove 'testtesttest' from top of readme.md (mkdecisiondev#5) * fix typo (mkdecisiondev#6) * added How to Pass a File Through API Gateway in markdown format * changes per review * Finished IAM article * image fixes * image fixes 2 * Reorganized folders * changes per review 2 * Started mfa article * Delete image12.PNG * Delete image7.PNG * Reformatted pass-file-through-API-gateway.md * More formatting * Finished formatting api gateway advanced doc * Update pass-file-through-API-gateway.md * Update pass-file-through-API-gateway.md * Update pass-file-through-API-gateway.md * Making formatting changes to my files * Reformatting introduction-to-lambda.md * Updated my api gateway doc * Added mocking article * Update aws-sdk-mock.md * Fixed formatting, unlinked one article * Added environmental variables article * Reorganized chapter hierarchy * Delete .DS_Store * Update readme.md * Started the writing to DynamoDB tutorial * Added SES tutorial * Delete image2.png * Delete image3.png * Update ses-lambda.md * Added new article title * Finished MFA article * Reverted numbering of Fundamental Technologies back to original numbering * Updated image references in credentials-setup.md * Updated another image reference * Readded images * Update credentials-setup.md * Added reference to readme * Update mfa.md * Update mfa.md * Added .DS_Store to .gitignore * Cropped unnecessary bits from mobile screenshots * Removed old versions of screenshots * Returned new versions of screenshots * Removed old versions of screenshots (attempt 2) * Re-added new versions of screenshots (attempt 2) * Fixed typo * Added S3 DynamoDB chapter * Renamed some files, updated readme * Added more information on the IAM article * Update readme.md * Edited image * Using SNS and Lambda to Send a Random 6 Digit Number Via Text Message (mkdecisiondev#10) * added How to Pass a File Through API Gateway in markdown format * minor changes * started documentation on SMS being sent by SNS * minor changes * sms function working, writing documentation * SNS 6 digit verification code SMS complete, ready for review * changes made to SMS text verification documentaion per review * Update send-sms-code-with-sns.md * Lambda write to dynamodb (mkdecisiondev#12) * complete documentation of initial lambda function, add beginning of test tutorial * complete documentation about writing to dynamodb with lambda function, delete unused image files * crop images/1.png * proof-reading * fix inline code snippets, remove explanation of iam and instead link to appropriate doc, remove unused images * implement requested changes from review * Update lambda-dynamodb.md * change examples of index.js to move const docClient declaration inside handler function. Move dexplanation of docClient accordingly to make sense in context * style all instances of 'index.js' as code snippets * added promisified docClient.put * update screenshot showing error for invalid params * Update javascript.md * Added Promises chapter * Update lambda-transfer-buckets.md * Update lambda-dynamodb.md * Update env-variables.md * Update introduction-to-lambda.md * Added Promise chapter and removed Authorship info
1 parent 6c3f98b commit 0adfdbc

130 files changed

Lines changed: 1926 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Mock Testing the AWS SDK
2+
3+
Testing is an important part of the development of a project. It provides reliability to the end product. Sometimes while testing, your functions will have a few dependencies, usually from an outside source, that can make the unit testing phase a bit tricky. In certain cases, running a unit test with dependencies can be impractical or impossible. For these cases, there is a method we can use to overcome these obstacles. This method is called "mocking".
4+
5+
Mocking simulates complex dependencies for use in testing. This avoids triggering actual live dependencies or having to meet specific criteria in order to execute your function. The mocking libraries are usually defined as variables at the top of the testing file with some exceptions we will go over later. For this example, we will be going over the mocking library for Amazon Web Services software development kit. (i.e. `aws-sdk`)
6+
7+
Below is a barebones S3 upload lambda function that will return a url once the upload is complete. Notice how this function is relying on the AWS SDK on the first line and how this function is creating a new S3 event inside the function.
8+
9+
```javascript
10+
const AWS = require('aws-sdk');
11+
12+
module.exports = function(filename, file, data) {
13+
const s3 = new AWS.S3();
14+
let params = {
15+
Bucket: 'testBucket',
16+
Key: filename,
17+
Body: file
18+
};
19+
return s3.upload(params).promise()
20+
.then(function (url) {
21+
return url.Location;
22+
});
23+
}
24+
```
25+
26+
To begin to use the AWS mocking library, we need to install it via the command line by typing in `pnpm install --save-dev aws-sdk-mock`. After the library finishes installing, we can start creating our testing file.
27+
28+
At the top of our testing file, we will need to "require" the mocking library and assign it to a const variable:
29+
30+
```javascript
31+
const AWS = require('aws-sdk-mock');
32+
```
33+
34+
This will grant access to the mocking library we have installed. We will then set up the skeleton of the chai testing function, including the describe/it functions and the remaining const variables.
35+
36+
```javascript
37+
const AWS = require('aws-sdk-mock');
38+
const sampleTestData = require('./sampleTestData.js');
39+
40+
// (Any dummy info you want to pass in goes here)
41+
42+
const uploadS3 = require('../lib/uploadS3.js');
43+
44+
//The upload file from above
45+
const expect = require('chai').expect;
46+
describe('aws-sdk-mock testing', function() {
47+
it('should give a successful output of an S3 upload', function() {
48+
let goodApple = sampleTestData;
49+
return uploadS3('resume.pdf', buffer, goodApple).then(function (url) {
50+
expect(url).to.be.a('string');
51+
});
52+
});
53+
}
54+
```
55+
56+
The problem with this test file is that it needs to call on the AWS SDK’s S3 class’s `upload()` function to complete, but because it’s a test, we don’t actually want to call to call this function, because we aren’t really uploading anything. So how do we go about making that happen? Well, now that we have the AWS SDK mocking library we can use an `AWS.mock()` function within our describe function to mock the actions of a real S3 upload.
57+
58+
Within the `describe()` function, but outside of the `it()` function, we need to make an `AWS.mock()` function that runs every time we want to run an it() function so we can simulate the S3 event. In this example, we are only running one `it()` function, but in the future we may want to run multiple. To run the mocking function every time, we can use a `beforeEach()` function and nest the `AWS.mock()` inside of it. The `beforeEach()` function and its equivalents (`afterEach()`, `before()`, and `after()`) are called "hooks". The `beforeEach()` function will execute a set of commands before each `it()` function is tested. As the names imply, `afterEach()` will run a series of commands after every `it()` function, while `before()` and `after()` will only run commands before and after all of the `it()` functions run, respectively.
59+
60+
Below is a typical framework for hooks:
61+
62+
```javascript
63+
describe('description', function() {
64+
beforeEach(function () {
65+
//...
66+
});
67+
68+
afterEach(function () {
69+
//...
70+
});
71+
72+
it('blah blah blah', function() {
73+
//...
74+
});
75+
});
76+
```
77+
78+
For more information on hooks, please see [here](https://medium.com/@kanyang/hooks-in-mocha-87cb43baa91c).
79+
80+
For this example, one of these commands that these hooks run will be an `AWS.mock()`. This function takes in several parameters including: which AWS platform to mock (e.g. DynamoDB, S3, SNS, etc.), which action to take in that platform (e.g. `upload`, `putItem`, `publish`, etc.), and a function that can define additional details for use by the mock. A typical `AWS.mock()` function designed for an S3 upload will look like this:
81+
82+
```javascript
83+
AWS.mock('S3', 'upload', function (params, callback) {
84+
// additional details here
85+
});
86+
```
87+
88+
Each `AWS.mock()` function can only be run once before needing to be reset. To reset the `AWS.mock()` function, we will use an `afterEach()` function after every `it()` function is executed to restore the mock library before the next `it()` function runs. For this we will use `AWS.restore()`. There are two ways to restore a mock library with this function. We can either target the platform and action we just used like this: `AWS.restore(‘S3’, ‘upload’);` or we can use a restore all option like this: `AWS.restore();`. The restore all option will restore every `AWS.mock()` you have used so far so be careful when using this command.
89+
90+
For more information on setting up and using `aws-sdk-mock`, look [here](https://github.com/dwyl/aws-sdk-mock).
91+
92+
If you put all of this together, it could look like something along these lines:
93+
94+
```javascript
95+
const AWS = require('aws-sdk-mock');
96+
const sampleTestData = require('./sampleTestData.js');
97+
const uploadS3 = require('../lib/uploadS3.js');
98+
const buffer = 'TestBuffer';
99+
100+
describe('aws-sdk mock testing', function() {
101+
beforeEach(function () {
102+
AWS.mock('S3', 'upload', function (params, callback) {
103+
expect(params).to.be.an('Object');
104+
expect(params).to.have.property('Bucket', 'TestBucket');
105+
expect(params).to.have.property('Key');
106+
expect(params).to.have.property('Body', 'TestBuffer');
107+
108+
callback(null, {
109+
ETag: 'SomeETag',
110+
Location: 'PublicWebsiteLink',
111+
Key: 'RandomKey',
112+
Bucket: 'TestBucket'
113+
});
114+
});
115+
});
116+
117+
afterEach(function () {
118+
AWS.restore('S3', 'upload');
119+
});
120+
121+
it('should give a successful output of an S3 upload', function() {
122+
let goodApple = sampleTestData;
123+
return uploadS3('resume.pdf', buffer, goodApple).then(function (url) {
124+
expect(url).to.be.a('string');
125+
});
126+
});
127+
});
128+
```
129+
130+
All there is left to do is run our test. For this example, we can use a simple `mocha test` in our command line, but with other project setups, you might need to run `pnpm run test`.
131+
132+
It cannot be said too often that there is a distinction between mock testing and regular unit testing. In regular unit testing, we need to account for everything that can go wrong in a process. However, in mock testing, we should always assume that the input we are receiving is absolutely correct. Mock testing should be reserved to only test the actual SDK’s expected behavior and nothing else. If there are any pitfalls before the actual mock is tested, then they should not be part of the actual testing of the mock. This is because in some cases, wrong information can be passed into a mocking test, yet result in a success. This is something to be aware of and consider with care. You should write any possible vanilla unit tests first to avoid any incorrect data being passed through a mock test.
9.72 KB
Loading
13.8 KB
Loading
5.34 KB
Loading
17.3 KB
Loading
31.7 KB
Loading
6.82 KB
Loading
112 KB
Loading
50.4 KB
Loading

0 commit comments

Comments
 (0)