SlideShare a Scribd company logo
1 of 49
Download to read offline
UNITTESTING NODE.JS
MIDDLEWARE
By Morris Singer
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
express and
ES15
Edition!
ABOUT ME
• Senior Software Engineer atVerilume
• I Like:
• Test-Driven Development
• Angular 1 and 2,Aurelia, Ionic, and
React.js, Node.js, and Cordova
AGENDA
• Define middleware and why it isn’t just
a fancy term for controllers or
endpoints.
• Review behavior-driven development
principles for unit testing.
• Argue why middleware are behavioral
units.
• Summarize common challenges testing
behavior in Express and Koa.
• Learn and implement a pattern for
Express and Koa Middleware.
• Answer questions. (10 minutes)
MIDDLEWARE
BuildingYour Product, One Layer at aTime
A SIMPLE CASE
One Middleware Per Endpoint
express
app.use(function (req, res, next) {
res.send('hello world');
});
A SIMPLE CASE
“Why is it called ‘Middleware’ anyway?”
app.use(function* (next) {
this.body = 'hello world';
});
• One Middleware Per Endpoint
MORE COMPLEX CASES
Two Ways of Stacking Middleware
Variadic Iterative
express
const middleware = [
function (req, res, next) {
req.message = 'HELLO WORLD';
next();
},
function (req, res, next) {
res.send(req.message.toLowerCase());
}
];
middleware.forEach(app.use);app.use(...middleware);
MORE COMPLEX CASES
Two Ways of Stacking Middleware
Variadic Iterative
app.use(...middleware);
const middleware = [
function* (next) => {
this.message = 'HELLO WORLD';
return yield next;
},
function* (next) => {
this.body = this.message.toLowerCase();
}
];
middleware.forEach(app.use);
THE MIDDLEWARE STACK
GET
Done
Generate
Message
Send Lowercase
Message
express
app.use(
function (req, res, next) {
req.message = 'HELLO WORLD';
next();
},
function (req, res, next) {
res.send(req.message.toLowerCase());
}
);
THE MIDDLEWARE STACK
GET
Done
Generate
Message
Assign Lowercase
to Body
app.use(
function (next) {
this.message = 'HELLO WORLD';
return yield next;
},
function (next) {
this.body = this.message.toLowerCase();
}
);
A B C
1
D E F
2
G H I
3
GET /
TEST BEHAVIOR
COMMON CHALLENGES
Or,Why Node Developers Often AvoidTDD
HTTP RESPONSETESTS
What happens when we add a middleware to the stack?
express
it('should return a 500 error', (done) => {
request({
method: 'POST',
url: 'http://localhost:3000/api/endpoint'
}, (error, response, body) => {
Assert.equal(response.statusCode, 500);
done();
});
});
TESTING MID-STACK
How do we pull out these anonymous functions?
express
const middleware = [
function (req, res, next) {
req.message = 'HELLO WORLD';
next();
},
function (req, res, next) {
res.send(req.message.toLowerCase());
}
];
middleware.forEach(app.use);
ILLUMINATINGTEST FAILURES
What happens if next() is not called?
express
import {httpMocks} from 'node-mocks-http';
it('should call next()', (done) => {
var req = httpMocks.createRequest(),
res = httpMocks.createResponse();
middleware(req, res, () => {
done();
});
});
KNOWING WHENTOTEST
When is the assertion run?
express
import {httpMocks} from 'node-mocks-http';
it('should call next()', () => {
var req = httpMocks.createRequest(),
res = httpMocks.createResponse();
middleware(req, res);
return Assert.equal(req.foo, 'bar');
});
TESTING WITH DATA
Where do data come from?
express
app.get('path/to/post', function (req, res, next) {
Post.findOne(params).exec(function (err, post) {
res.json(post);
});
});
DEALING WITH POLLUTION
How does one reset the data?
express
it('should update the first post', () => {
/* ... */
});
it('should get the first post', () => {
/* ... */
});
MOCKING DEPENDENCIES
How does one cut out the external data source?
express
app.get('endpoint', function (req, res, next) {
request({
method: 'GET',
url: 'http://example.com/api/call'
}, (error, response, body) => {
req.externalData = body;
next();
});
});
MIDDLEWARE + SEPARATION OF CONCERNS
+ FLOW CONTROL
The “Eureka” Moment
OVERVIEW
• Pull behavior into middleware and tests.
• Use promises or generators as flow control.
• Return client-server interaction to endpoint.
• Use promises or generators with Mocha.
PULL BEHAVIOR INTO
MIDDLEWARE,TESTS
Endpoint
Test
BehaviorBehavior
BehaviorBehavior
Endpoint
TestTest
Old Paradigm
New Paradigm
PULL BEHAVIOR INTO ENDPOINTS
Old Paradigm New Paradigm
N.B.:This only looks like a lot more code…
express
const middleware = [
function (req, res, next) {
/* Behavior */
},
function (req, res, next) {
/* Behavior */
}
];
app.use(...middleware);
const behavior = {
first: function () {},
second: function () {}
};
const middleware = [
function (req, res, next) {
behavior.first();
next();
},
function (req, res, next) {
behavior.second();
next();
}
];
app.use(...middleware);
PULL BEHAVIOR INTO ENDPOINTS
Old Paradigm New Paradigm
const middleware = [
function* (next) {
/* Behavior */
},
function* (next) {
/* Behavior */
}
];
app.use(...middleware);
const behavior = {
first: function* () {},
second: function* () {}
};
const middleware = [
function* (next) {
yield behavior.first();
return yield next;
},
function* (next) {
yield behavior.second();
return next;
}
];
app.use(...middleware);
USE PROMISES AS FLOW CONTROL
• Clean, standardized interface between asynchronous
behavior and endpoints.
• Both endpoints and tests can leverage the same mechanism
in the behavior for serializing logic.
express
USE PROMISES AS FLOW CONTROL
Old Paradigm
New Paradigm
express
export function middleware (req, res, next) {
/* Define behavior and call res.json(),
next(), etc. */
};
export function behavior () {
return new Promise((resolve, reject) => {
/* Define behavior and resolve or
reject promise. */
};
}
USE GENERATORS (WITH CO) AS FLOW CONTROL
• Same interface between asynchronous behavior and
middleware as already used between successive middleware.
• Both endpoints and tests can leverage the same mechanism
in the behavior for serializing logic.
CO
Generator based control flow goodness for nodejs and the browser,
using promises, letting you write non-blocking code in a nice-ish way.
https://www.npmjs.com/package/co
USE GENERATORS AS LINK BETWEEN
MIDDLEWARE AND ENDPOINTS
Old Paradigm
New Paradigm
export function* middleware (next) {
/* Call with assigned context and
leverage behavior on the Koa context,
yield next, etc.*/
};
export function* behavior () {
/* Define behavior and yield values. */
}
RETURN CLIENT-SERVER
INTERACTIONTO ENDPOINT
Endpoint
Res
Req
Behavior
Res
Req
Client
Endpoint
Value
Object
Behavior
Value
Object
Client
Old Paradigm
New Paradigm
RETURN CLIENT-SERVER
INTERACTIONTO ENDPOINT
Old Paradigm New Paradigm
express
const middleware = [
function (req, res, next) {},
function (req, res, next) {}
];
app.use(...middleware);
const behavior = [
function () {},
function () {}
];
const middleware = [
function (req, res, next) {
behavior[0](/* Pass objects, values */)
.then(function () { next(); })
.catch(res.json);
},
function (req, res, next) {
behavior[1](/* Pass objects, values */)
.then(function () { next(); })
.catch(res.json);
}
];
app.use(...middleware);
RETURN CLIENT-SERVER
INTERACTIONTO ENDPOINT
Old Paradigm New Paradigm
express
const middleware = [
function (req, res, next) {},
function (req, res, next) {}
];
app.use(...middleware);
const behavior = [
function () {},
function () {}
];
const middleware = behavior.map((func) => {
return function (req, res, next) {
func()
.then(function () { next(); })
.catch(res.json);
}
};
app.use(...middleware);
RETURN CLIENT-SERVER
INTERACTIONTO ENDPOINT
Old Paradigm New Paradigm
express
const middleware = [
function (req, res, next) {},
function (req, res, next) {}
];
app.use(...middleware);
const behavior = [
function () {},
function () {}
];
const middleware = behavior.map((func) => {
return function(args) {
return function (req, res, next) {
func()
.then(function () { next(); })
.catch(res.json);
}
}
};
app.use(
middleware[0](/* Pass objects, values */),
middleware[1](/* Pass objects, values */)
);
RETURN CLIENT-SERVER
INTERACTIONTO ENDPOINT
Old Paradigm New Paradigm
const middleware = [
function* (next) {},
function* (next) {}
];
app.use(...middleware);
const behavior = [
function* () {},
function* () {}
];
const middleware = [
function* (next) {
yield behavior[0](/* Pass objects, values */);
return yield next;
},
function* (next) {
yield behavior[1](/* Pass objects, values */);
return yield next;
}
];
app.use(...middleware);
USING PROMISES WITH MOCHA
We need:
• A test framework syntax that facilitates easy async testing.
(Supported natively in Mocha since 1.18.0)
• An assertion syntax that we are familiar with. (Assert)
• A set of assertions that facilitate easily writing tests of
promises. (assertPromise)
express
USING PROMISES WITH
MOCHA (ASSERT_PROMISE)
Old Paradigm
New Paradigm
express
describe('behavior', () => {
it ('resolves under condition X with result Y', (done) => {
behavior().then(function (done) {
/* Assert here. */
}).finally(done);
});
});
import {assertPromise} from 'assert-promise';
describe('behavior', () => {
it ('resolves under condition X with result Y', () => {
return assertPromise.equal(behavior(), 'value');
});
});
USING GENERATORS WITH MOCHA
We need:
• Use the same async flow that Koa leverages (ES15 generators
and co)
• An assertion syntax that we are familiar with. (Assert)
• Mocha syntax that facilitates easily writing tests of generators
with co. (co-mocha)
CO-MOCHA
Enable support for generators in Mocha tests using co.
https://www.npmjs.com/package/co-mocha
USING PROMISES WITH
MOCHA (CO-MOCHA)
Old Paradigm
(No Co-Mocha)
New Paradigm
describe('behavior', () => {
it ('resolves under condition X with result Y', (done) => {
behavior().then(function () {
/* Assert here. */
}).finally(done);
});
});
describe('behavior', () => {
it ('resolves under condition X with result Y', function* () {
return Assert.equal(yield behavior(), 'value');
});
});
PUTTING IT ALLTOGETHER
“Detroit Industry” by Diego Rivera
Return Client-Server
Interaction to Endpoints
ENDPOINTS
Pull Behavior
into Endpoint
import {behavior} from './behavior.js';
app.use(function (req, res, next) {
behavior()
.then(function () { next(); })
.catch(res.json)
});
express
Use Promise as
Flow Control
BEHAVIOR
export function behavior (req, res, next) {
return new Promise(function (resolve, reject) {
/* Define behavior and resolve or reject. */
}
};
express
Pull Behavior IntoTests
TEST
Use Promises with Mochaimport {assertPromise} from "assert-promise";
var behavior = require('./behavior.js');
describe('behavior', () => {
it ('resolves under condition X with result Y', () => {
return assertPromise.equal(behavior(), 'value');
});
});
express
Return Client-Server
Interaction to Endpoints
ENDPOINTS
Pull Behavior
into Endpoint
import {behavior} from './behavior.js';
app.use(function* (next) {
let message = yield behavior();
this.body = message;
});
Use Generators as
Flow Control
BEHAVIOR
export function* behavior (next) {
yield asyncRequest();
return yield next;
};
Pull Behavior IntoTests
TEST
var behavior = require('./behavior.js');
describe('behavior', () => {
it ('resolves under condition X with result Y', function* () {
return Assert.equal(yield behavior(), 'value');
});
});
QUESTIONS
GET INTOUCH
! @morrissinger
" linkedin.com/in/morrissinger
# morrissinger.com
$ github.com/morrissinger

More Related Content

What's hot

Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...HostedbyConfluent
 
인생은 짧아요, 엑셀 대신 파이썬
인생은 짧아요, 엑셀 대신 파이썬인생은 짧아요, 엑셀 대신 파이썬
인생은 짧아요, 엑셀 대신 파이썬Seung-June Lee
 
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들Brian Hong
 
차곡차곡 쉽게 알아가는 Elasticsearch와 Node.js
차곡차곡 쉽게 알아가는 Elasticsearch와 Node.js차곡차곡 쉽게 알아가는 Elasticsearch와 Node.js
차곡차곡 쉽게 알아가는 Elasticsearch와 Node.jsHeeJung Hwang
 
Dbs302 driving a realtime personalization engine with cloud bigtable
Dbs302  driving a realtime personalization engine with cloud bigtableDbs302  driving a realtime personalization engine with cloud bigtable
Dbs302 driving a realtime personalization engine with cloud bigtableCalvin French-Owen
 
Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...
Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...
Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...confluent
 
Djangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組みDjangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組みShinya Okano
 
[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?용민 박
 
高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓く
高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓く高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓く
高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓くHideki Takase
 
검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민종민 김
 
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XpressEngine
 
Reactive Programming for Real Use Cases
Reactive Programming for Real Use CasesReactive Programming for Real Use Cases
Reactive Programming for Real Use CasesAlex Soto
 
Tcp ip & io model
Tcp ip & io modelTcp ip & io model
Tcp ip & io modelNam Hyeonuk
 
삶이편해지는_백엔드_개발자_지식.pdf
삶이편해지는_백엔드_개발자_지식.pdf삶이편해지는_백엔드_개발자_지식.pdf
삶이편해지는_백엔드_개발자_지식.pdfSeung kyoo Park
 
대용량 분산 아키텍쳐 설계 #5. rest
대용량 분산 아키텍쳐 설계 #5. rest대용량 분산 아키텍쳐 설계 #5. rest
대용량 분산 아키텍쳐 설계 #5. restTerry Cho
 
CircleCI vs. CodePipeline
CircleCI vs. CodePipelineCircleCI vs. CodePipeline
CircleCI vs. CodePipelineHonMarkHunt
 
JavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だったJavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だったiPride Co., Ltd.
 

What's hot (20)

実践 NestJS
実践 NestJS実践 NestJS
実践 NestJS
 
SREチームとしてSREしてみた話
SREチームとしてSREしてみた話SREチームとしてSREしてみた話
SREチームとしてSREしてみた話
 
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
Building an Interactive Query Service in Kafka Streams With Bill Bejeck | Cur...
 
인생은 짧아요, 엑셀 대신 파이썬
인생은 짧아요, 엑셀 대신 파이썬인생은 짧아요, 엑셀 대신 파이썬
인생은 짧아요, 엑셀 대신 파이썬
 
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
[DEVIEW 2021] 1000만 글로벌 유저를 지탱하는 기술과 사람들
 
차곡차곡 쉽게 알아가는 Elasticsearch와 Node.js
차곡차곡 쉽게 알아가는 Elasticsearch와 Node.js차곡차곡 쉽게 알아가는 Elasticsearch와 Node.js
차곡차곡 쉽게 알아가는 Elasticsearch와 Node.js
 
...Lag
...Lag...Lag
...Lag
 
Dbs302 driving a realtime personalization engine with cloud bigtable
Dbs302  driving a realtime personalization engine with cloud bigtableDbs302  driving a realtime personalization engine with cloud bigtable
Dbs302 driving a realtime personalization engine with cloud bigtable
 
Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...
Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...
Why My Streaming Job is Slow - Profiling and Optimizing Kafka Streams Apps (L...
 
Djangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組みDjangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組み
 
[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?[네트워크] TCP, 믿을 수 있나요!?
[네트워크] TCP, 믿을 수 있나요!?
 
高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓く
高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓く高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓く
高い並列性能と耐障害性を持つElixirとNervesでIoTの新しいカタチを切り拓く
 
검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민검색엔진이 데이터를 다루는 법 김종민
검색엔진이 데이터를 다루는 법 김종민
 
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
XECon+PHPFest2014 발표자료 - ElasticSearch를 이용한 통합검색 구축방법 - 김훈민
 
Reactive Programming for Real Use Cases
Reactive Programming for Real Use CasesReactive Programming for Real Use Cases
Reactive Programming for Real Use Cases
 
Tcp ip & io model
Tcp ip & io modelTcp ip & io model
Tcp ip & io model
 
삶이편해지는_백엔드_개발자_지식.pdf
삶이편해지는_백엔드_개발자_지식.pdf삶이편해지는_백엔드_개발자_지식.pdf
삶이편해지는_백엔드_개발자_지식.pdf
 
대용량 분산 아키텍쳐 설계 #5. rest
대용량 분산 아키텍쳐 설계 #5. rest대용량 분산 아키텍쳐 설계 #5. rest
대용량 분산 아키텍쳐 설계 #5. rest
 
CircleCI vs. CodePipeline
CircleCI vs. CodePipelineCircleCI vs. CodePipeline
CircleCI vs. CodePipeline
 
JavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だったJavaScriptでSQLを唱えたいだけの人生だった
JavaScriptでSQLを唱えたいだけの人生だった
 

Similar to Unit Testing Express and Koa Middleware in ES2015

Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express MiddlewareMorris Singer
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.jsdavidchubbs
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with ExpressAaron Stannard
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013Laurent_VB
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express Jeetendra singh
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Codemotion
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Visual Engineering
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiRan Mizrahi
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Module design pattern i.e. express js
Module design pattern i.e. express jsModule design pattern i.e. express js
Module design pattern i.e. express jsAhmed Assaf
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications Juliana Lucena
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascriptEldar Djafarov
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETGianluca Carucci
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every dayVadym Khondar
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 

Similar to Unit Testing Express and Koa Middleware in ES2015 (20)

Unit Testing Express Middleware
Unit Testing Express MiddlewareUnit Testing Express Middleware
Unit Testing Express Middleware
 
Middleware.pdf
Middleware.pdfMiddleware.pdf
Middleware.pdf
 
Build Web Apps using Node.js
Build Web Apps using Node.jsBuild Web Apps using Node.js
Build Web Apps using Node.js
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Building Web Apps with Express
Building Web Apps with ExpressBuilding Web Apps with Express
Building Web Apps with Express
 
Developing web-apps like it's 2013
Developing web-apps like it's 2013Developing web-apps like it's 2013
Developing web-apps like it's 2013
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
Going fullstack React(ive) - Paulo Lopes - Codemotion Amsterdam 2017
 
Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.Workshop 4: NodeJS. Express Framework & MongoDB.
Workshop 4: NodeJS. Express Framework & MongoDB.
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Module design pattern i.e. express js
Module design pattern i.e. express jsModule design pattern i.e. express js
Module design pattern i.e. express js
 
Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications  Ember.js - A JavaScript framework for creating ambitious web applications
Ember.js - A JavaScript framework for creating ambitious web applications
 
Intro to Node
Intro to NodeIntro to Node
Intro to Node
 
node.js practical guide to serverside javascript
node.js practical guide to serverside javascriptnode.js practical guide to serverside javascript
node.js practical guide to serverside javascript
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 

Recently uploaded

Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 

Recently uploaded (20)

Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 

Unit Testing Express and Koa Middleware in ES2015

  • 1. UNITTESTING NODE.JS MIDDLEWARE By Morris Singer This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. express and ES15 Edition!
  • 2. ABOUT ME • Senior Software Engineer atVerilume • I Like: • Test-Driven Development • Angular 1 and 2,Aurelia, Ionic, and React.js, Node.js, and Cordova
  • 3. AGENDA • Define middleware and why it isn’t just a fancy term for controllers or endpoints. • Review behavior-driven development principles for unit testing. • Argue why middleware are behavioral units. • Summarize common challenges testing behavior in Express and Koa. • Learn and implement a pattern for Express and Koa Middleware. • Answer questions. (10 minutes)
  • 5. A SIMPLE CASE One Middleware Per Endpoint express app.use(function (req, res, next) { res.send('hello world'); });
  • 6. A SIMPLE CASE “Why is it called ‘Middleware’ anyway?” app.use(function* (next) { this.body = 'hello world'; }); • One Middleware Per Endpoint
  • 7. MORE COMPLEX CASES Two Ways of Stacking Middleware Variadic Iterative express const middleware = [ function (req, res, next) { req.message = 'HELLO WORLD'; next(); }, function (req, res, next) { res.send(req.message.toLowerCase()); } ]; middleware.forEach(app.use);app.use(...middleware);
  • 8. MORE COMPLEX CASES Two Ways of Stacking Middleware Variadic Iterative app.use(...middleware); const middleware = [ function* (next) => { this.message = 'HELLO WORLD'; return yield next; }, function* (next) => { this.body = this.message.toLowerCase(); } ]; middleware.forEach(app.use);
  • 9. THE MIDDLEWARE STACK GET Done Generate Message Send Lowercase Message express app.use( function (req, res, next) { req.message = 'HELLO WORLD'; next(); }, function (req, res, next) { res.send(req.message.toLowerCase()); } );
  • 10. THE MIDDLEWARE STACK GET Done Generate Message Assign Lowercase to Body app.use( function (next) { this.message = 'HELLO WORLD'; return yield next; }, function (next) { this.body = this.message.toLowerCase(); } );
  • 11. A B C 1 D E F 2 G H I 3 GET /
  • 13. COMMON CHALLENGES Or,Why Node Developers Often AvoidTDD
  • 14. HTTP RESPONSETESTS What happens when we add a middleware to the stack? express it('should return a 500 error', (done) => { request({ method: 'POST', url: 'http://localhost:3000/api/endpoint' }, (error, response, body) => { Assert.equal(response.statusCode, 500); done(); }); });
  • 15. TESTING MID-STACK How do we pull out these anonymous functions? express const middleware = [ function (req, res, next) { req.message = 'HELLO WORLD'; next(); }, function (req, res, next) { res.send(req.message.toLowerCase()); } ]; middleware.forEach(app.use);
  • 16. ILLUMINATINGTEST FAILURES What happens if next() is not called? express import {httpMocks} from 'node-mocks-http'; it('should call next()', (done) => { var req = httpMocks.createRequest(), res = httpMocks.createResponse(); middleware(req, res, () => { done(); }); });
  • 17. KNOWING WHENTOTEST When is the assertion run? express import {httpMocks} from 'node-mocks-http'; it('should call next()', () => { var req = httpMocks.createRequest(), res = httpMocks.createResponse(); middleware(req, res); return Assert.equal(req.foo, 'bar'); });
  • 18. TESTING WITH DATA Where do data come from? express app.get('path/to/post', function (req, res, next) { Post.findOne(params).exec(function (err, post) { res.json(post); }); });
  • 19. DEALING WITH POLLUTION How does one reset the data? express it('should update the first post', () => { /* ... */ }); it('should get the first post', () => { /* ... */ });
  • 20. MOCKING DEPENDENCIES How does one cut out the external data source? express app.get('endpoint', function (req, res, next) { request({ method: 'GET', url: 'http://example.com/api/call' }, (error, response, body) => { req.externalData = body; next(); }); });
  • 21. MIDDLEWARE + SEPARATION OF CONCERNS + FLOW CONTROL The “Eureka” Moment
  • 22. OVERVIEW • Pull behavior into middleware and tests. • Use promises or generators as flow control. • Return client-server interaction to endpoint. • Use promises or generators with Mocha.
  • 24. PULL BEHAVIOR INTO ENDPOINTS Old Paradigm New Paradigm N.B.:This only looks like a lot more code… express const middleware = [ function (req, res, next) { /* Behavior */ }, function (req, res, next) { /* Behavior */ } ]; app.use(...middleware); const behavior = { first: function () {}, second: function () {} }; const middleware = [ function (req, res, next) { behavior.first(); next(); }, function (req, res, next) { behavior.second(); next(); } ]; app.use(...middleware);
  • 25. PULL BEHAVIOR INTO ENDPOINTS Old Paradigm New Paradigm const middleware = [ function* (next) { /* Behavior */ }, function* (next) { /* Behavior */ } ]; app.use(...middleware); const behavior = { first: function* () {}, second: function* () {} }; const middleware = [ function* (next) { yield behavior.first(); return yield next; }, function* (next) { yield behavior.second(); return next; } ]; app.use(...middleware);
  • 26. USE PROMISES AS FLOW CONTROL • Clean, standardized interface between asynchronous behavior and endpoints. • Both endpoints and tests can leverage the same mechanism in the behavior for serializing logic. express
  • 27. USE PROMISES AS FLOW CONTROL Old Paradigm New Paradigm express export function middleware (req, res, next) { /* Define behavior and call res.json(), next(), etc. */ }; export function behavior () { return new Promise((resolve, reject) => { /* Define behavior and resolve or reject promise. */ }; }
  • 28. USE GENERATORS (WITH CO) AS FLOW CONTROL • Same interface between asynchronous behavior and middleware as already used between successive middleware. • Both endpoints and tests can leverage the same mechanism in the behavior for serializing logic.
  • 29. CO Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way. https://www.npmjs.com/package/co
  • 30. USE GENERATORS AS LINK BETWEEN MIDDLEWARE AND ENDPOINTS Old Paradigm New Paradigm export function* middleware (next) { /* Call with assigned context and leverage behavior on the Koa context, yield next, etc.*/ }; export function* behavior () { /* Define behavior and yield values. */ }
  • 32. RETURN CLIENT-SERVER INTERACTIONTO ENDPOINT Old Paradigm New Paradigm express const middleware = [ function (req, res, next) {}, function (req, res, next) {} ]; app.use(...middleware); const behavior = [ function () {}, function () {} ]; const middleware = [ function (req, res, next) { behavior[0](/* Pass objects, values */) .then(function () { next(); }) .catch(res.json); }, function (req, res, next) { behavior[1](/* Pass objects, values */) .then(function () { next(); }) .catch(res.json); } ]; app.use(...middleware);
  • 33. RETURN CLIENT-SERVER INTERACTIONTO ENDPOINT Old Paradigm New Paradigm express const middleware = [ function (req, res, next) {}, function (req, res, next) {} ]; app.use(...middleware); const behavior = [ function () {}, function () {} ]; const middleware = behavior.map((func) => { return function (req, res, next) { func() .then(function () { next(); }) .catch(res.json); } }; app.use(...middleware);
  • 34. RETURN CLIENT-SERVER INTERACTIONTO ENDPOINT Old Paradigm New Paradigm express const middleware = [ function (req, res, next) {}, function (req, res, next) {} ]; app.use(...middleware); const behavior = [ function () {}, function () {} ]; const middleware = behavior.map((func) => { return function(args) { return function (req, res, next) { func() .then(function () { next(); }) .catch(res.json); } } }; app.use( middleware[0](/* Pass objects, values */), middleware[1](/* Pass objects, values */) );
  • 35. RETURN CLIENT-SERVER INTERACTIONTO ENDPOINT Old Paradigm New Paradigm const middleware = [ function* (next) {}, function* (next) {} ]; app.use(...middleware); const behavior = [ function* () {}, function* () {} ]; const middleware = [ function* (next) { yield behavior[0](/* Pass objects, values */); return yield next; }, function* (next) { yield behavior[1](/* Pass objects, values */); return yield next; } ]; app.use(...middleware);
  • 36. USING PROMISES WITH MOCHA We need: • A test framework syntax that facilitates easy async testing. (Supported natively in Mocha since 1.18.0) • An assertion syntax that we are familiar with. (Assert) • A set of assertions that facilitate easily writing tests of promises. (assertPromise) express
  • 37. USING PROMISES WITH MOCHA (ASSERT_PROMISE) Old Paradigm New Paradigm express describe('behavior', () => { it ('resolves under condition X with result Y', (done) => { behavior().then(function (done) { /* Assert here. */ }).finally(done); }); }); import {assertPromise} from 'assert-promise'; describe('behavior', () => { it ('resolves under condition X with result Y', () => { return assertPromise.equal(behavior(), 'value'); }); });
  • 38. USING GENERATORS WITH MOCHA We need: • Use the same async flow that Koa leverages (ES15 generators and co) • An assertion syntax that we are familiar with. (Assert) • Mocha syntax that facilitates easily writing tests of generators with co. (co-mocha)
  • 39. CO-MOCHA Enable support for generators in Mocha tests using co. https://www.npmjs.com/package/co-mocha
  • 40. USING PROMISES WITH MOCHA (CO-MOCHA) Old Paradigm (No Co-Mocha) New Paradigm describe('behavior', () => { it ('resolves under condition X with result Y', (done) => { behavior().then(function () { /* Assert here. */ }).finally(done); }); }); describe('behavior', () => { it ('resolves under condition X with result Y', function* () { return Assert.equal(yield behavior(), 'value'); }); });
  • 41. PUTTING IT ALLTOGETHER “Detroit Industry” by Diego Rivera
  • 42. Return Client-Server Interaction to Endpoints ENDPOINTS Pull Behavior into Endpoint import {behavior} from './behavior.js'; app.use(function (req, res, next) { behavior() .then(function () { next(); }) .catch(res.json) }); express
  • 43. Use Promise as Flow Control BEHAVIOR export function behavior (req, res, next) { return new Promise(function (resolve, reject) { /* Define behavior and resolve or reject. */ } }; express
  • 44. Pull Behavior IntoTests TEST Use Promises with Mochaimport {assertPromise} from "assert-promise"; var behavior = require('./behavior.js'); describe('behavior', () => { it ('resolves under condition X with result Y', () => { return assertPromise.equal(behavior(), 'value'); }); }); express
  • 45. Return Client-Server Interaction to Endpoints ENDPOINTS Pull Behavior into Endpoint import {behavior} from './behavior.js'; app.use(function* (next) { let message = yield behavior(); this.body = message; });
  • 46. Use Generators as Flow Control BEHAVIOR export function* behavior (next) { yield asyncRequest(); return yield next; };
  • 47. Pull Behavior IntoTests TEST var behavior = require('./behavior.js'); describe('behavior', () => { it ('resolves under condition X with result Y', function* () { return Assert.equal(yield behavior(), 'value'); }); });
  • 49. GET INTOUCH ! @morrissinger " linkedin.com/in/morrissinger # morrissinger.com $ github.com/morrissinger