SlideShare une entreprise Scribd logo
1  sur  149
MODULE

DEVELOPMENT
What is node.js?

“

Node.js is a platform built on
Chrome's JavaScript runtime for
easily building fast, scalable network
applications.

”
./
sourceControl
git	
  init
javascriptFiles
mkdir	
  ./lib
executableFiles
mkdir	
  ./bin
testFiles
mkdir	
  ./test
documentationFiles
mkdir	
  ./doc
mkdir	
  ./example
mkdir	
  ./man
informationalFiles
touch	
  ./README
touch	
  ./LICENSE
touch	
  ./AUTHOR
./bin
./doc
./example
./lib
./man
./test

singularNouns
packageManagement
Package Manager
github: isaacs/npm
install: comes with node
localInstallation
npm install <package>
globalInstallation
npm install <package> --global
-g or --global
dualInstallation
npm install <package> --link
dependencyReferences
npm install <package> --save[-dev]
--save or --save-dev
updateDependencies
npm install
packageInitialization
npm init
$	
  npm	
  init
name: (sample-node) Sample
version: (0.0.0) 0.1.0
description: This is a sample module
entry point: (index.js) _
author:	
  Jay	
  Harris
license:	
  (BSD)	
  BSD
About	
  to	
  write	
  to	
  /Projects/sample-­‐node/package.json:
{
	
  	
  "name":	
  "Sample",
	
  	
  "version":	
  "0.1.0",
	
  	
  "description":	
  "This	
  is	
  a	
  sample	
  module",
	
  	
  "main":	
  "index.js",
	
  	
  "scripts":	
  {
	
  	
  	
  	
  "test":	
  "echo	
  "Error:	
  no	
  test	
  specified"	
  &&	
  exit	
  1"
	
  	
  },
	
  	
  "author":	
  "Jay	
  Harris",
	
  	
  "license":	
  "BSD"
}
Is	
  this	
  ok?	
  (yes)	
  _
./package.json
1 {
"name": "Sample",
2
"version": "0.1.0",
3
"description": "This is a sample module",
4
"main": "index.js",
5
"scripts": {
6
"test": "echo "Error: no tests avail." && exit 1"
7
},
8
"author": "Jay Harris",
9
"license": "BSD"
10
11 }
12
13
14
15
16
npm init is additive not destructive
moduleCreation
module
module.exports
./lib/sample.js
1 module.exports.sayHello = function() {
return "Hello World!";
2
3 }
4
5
6
7
8
9
10
11
12
13
14
15
16
var	
  sample	
  =	
  require("./lib/sample.js");
//	
  Returns	
  'Hello	
  World!'
sample.sayHello();
./lib/person.js
1 function Person(first, last) {
if (!(this instanceof Person)) {
2
return new Person(first, last);
3
}
4
5
this.firstName = first;
6
this.lastName = last;
7
8
return this;
9
10 }
11
12 module.exports = Person;
13
14
15
16
var person = require("./lib/person.js");
// This will return undefined
person.firstName;
// This will return 'Jay'
var jayHarris = new Person('Jay','Harris');
jayHarris.firstName;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

function Person(first, last) {
// ...
}
module.exports = Person;
// This is a public method;
Person.prototype.sayHello = function() {
return _join.call(this, "Hello", this.firstName);
}
// This is a private method
var _join(first, second) {
return first + ' ' + second;
}
var	
  person	
  =	
  require("./lib/person.js");
//	
  This	
  will	
  throw	
  'Has	
  No	
  Method'	
  error
person.sayHello();
//	
  This	
  will	
  return	
  'Hello	
  Jay'
var	
  jayHarris	
  =	
  new	
  Person('Jay','Harris');
jayHarris.sayHello();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

function Person(first, last) {
// ...
}
module.exports = Person;
// This is a static method
module.exports.sayHello = function() {
return "Hello World!";
}
// This is a public instance method;
Person.prototype.sayHello = function() {
return _join.call(this, "Hello", this.firstName);
}
// This is a private method
var _join(first, second) {
return first + ' ' + second;
}
var	
  person	
  =	
  require("./lib/person.js");
//	
  This	
  will	
  return	
  'Hello	
  World!'
person.sayHello();
//	
  This	
  will	
  return	
  'Hello	
  Jay'
var	
  jayHarris	
  =	
  new	
  Person('Jay','Harris');
jayHarris.sayHello();
eventEmitter
var	
  EventEmitter	
  =	
  require('events').EventEmitter;
EventEmitter.call(this);
var	
  util	
  =	
  require('util');
//	
  ...
util.inherits(MyClass,	
  EventEmitter);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var EventEmitter = require('events').EventEmitter
, util = require('util');
function Person(first, last) {
// ...
EventEmitter.call(this);
// ...
}
util.inherits(Person, EventEmitter);
Person.prototype.goToBed = function() {
this.emit("sleep");
}
var	
  person	
  =	
  require("./person.js");
//	
  This	
  will	
  return	
  'Hello	
  Jay'
var	
  jayHarris	
  =	
  new	
  Person('Jay','Harris');
jayHarris.on("sleep",	
  function()	
  {
	
  	
  	
  	
  console.log("Goodnight,	
  Jay");
}
jayHarris.goToBed();
//	
  Output	
  'Goodnight,	
  Jay'
testingNode.js
“

TDD is to coding style as yoga is
to posture. Even when you're not
actively practicing, having done so
colors your whole life healthier.

”

j. kerr
assertingCorrectness
var	
  assert	
  =	
  require('assert');
assert(value)
	
  	
  	
  	
  	
  	
  .ok(value)
	
  	
  	
  	
  	
  	
  .equal(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .deepEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notDeepEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .strictEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .notStrictEqual(actual,	
  expected)
	
  	
  	
  	
  	
  	
  .throws(block,	
  [error])
	
  	
  	
  	
  	
  	
  .doesNotThrow(block,	
  [error])
	
  	
  	
  	
  	
  	
  .ifError(value)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var assert = require('assert');
// Will pass
assert.ok(true);
// Will throw an exception
assert.ok(false);
1 var assert = require('assert');
2
3 // Will throw 'false == true' error
4 assert.ok(typeof 'hello' === 'number');
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$	
  node	
  test.js
assert.js:104
	
  	
  throw	
  new	
  assert.AssertionError({
	
  	
  	
  	
  	
  	
  	
  	
  ^
AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  at	
  Object.<anonymous>	
  (my-­‐test.js:7:8)
	
  	
  	
  	
  at	
  Module._compile	
  (module.js:449:26)
	
  	
  	
  	
  at	
  Object.Module._extensions..js	
  (module.js:467:10)
	
  	
  	
  	
  at	
  Module.load	
  (module.js:356:32)
	
  	
  	
  	
  at	
  Function.Module._load	
  (module.js:312:12)
	
  	
  	
  	
  at	
  Module.runMain	
  (module.js:487:10)
	
  	
  	
  	
  at	
  process.startup.processNextTick.process._tick...
$	
  _
Chai Assertion Library
github: chaijs/chai
install: npm install chai
isTrue,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isFalse,
isNull,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotNull,
isUndefined,	
  	
  	
  	
  	
  	
  isDefined,
isFunction,	
  	
  	
  	
  	
  	
  	
  isNotFunction,
isArray,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotArray,
isBoolean,	
  	
  	
  	
  	
  	
  	
  	
  isNotBoolean,
isNumber,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotNumber,
isString,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotString,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  include,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  lengthOf,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  operator,
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  closeTo	
  
isObject,	
  	
  	
  	
  	
  	
  	
  	
  	
  isNotObject,
typeOf,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  notTypeOf,
instanceOf,	
  	
  	
  	
  	
  	
  	
  notInstanceOf,
match,	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  notMatch,
property,	
  	
  	
  	
  	
  	
  	
  	
  	
  notProperty,
deepProperty,	
  	
  	
  	
  	
  notDeepProperty,
propertyVal,	
  	
  	
  	
  	
  	
  propertyNotVal,
deepPropertyVal,	
  	
  deepPropertyNotVal,

additional
assertions
var	
  assert	
  =	
  require('chai').assert;
1 var assert = require('chai').assert;
2
3 // Will throw 'expected 'hello' to be a number'
4 assert.isNumber('hello');
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$	
  node	
  test.js
expected	
  'hello'	
  to	
  be	
  a	
  number
$	
  _
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var chai
= require('chai')
, assert = chai.assert;
chai.Assertion.includeStack = true;
// Will throw and display stack
assert.isNumber('hello');
expectAssertions
assertSyntax
assert.isObject(person);
assert.property(person,	
  "age");
assert.isNumber(person.age);
assert.equals(person.age,	
  34);

expectSyntax
expect(person).to.be.an('object');
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.a('number')
	
  	
  	
  	
  .that.equals(34);
var	
  expect	
  =	
  require('chai').expect;
assertionChains
for readability
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
.to
.be
.been
.is
.that
.and
.have
.with

syntaxSugar
for readability
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
expect(person).to.exist
	
  	
  	
  	
  .and.be.an('object')
	
  	
  	
  	
  .with.property('age')
	
  	
  	
  	
  .that.is.to.exist
	
  	
  	
  	
  .and.is.a('number')
	
  	
  	
  	
  .and.equals(34);
.property

subjectChange
from original object
expect(person)
	
  	
  .that.is.an('object')
	
  	
  .with.property('address')
	
  	
  	
  	
  .that.is.an('object')
	
  	
  	
  	
  .with.property('city')
	
  	
  	
  	
  	
  	
  .that.is.a('string')
	
  	
  	
  	
  	
  	
  .and.equals('Detroit')
testingFramework
mocha

simple, flexible, fun
mocha

github: visionmedia/mocha
install: npm install -g mocha
$	
  npm	
  install	
  -­‐g	
  mocha
$	
  mkdir	
  test
$	
  mocha
	
  	
  
	
  	
  ✔	
  0	
  tests	
  complete	
  (1ms)
$	
  
var	
  mocha	
  =	
  require('mocha');
bddSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
./test/my-test.js
1 var assert = require('assert');
2
3 describe('Assertions', function() {
it('should pass on truthiness', function() {
4
assert.ok(true);
5
});
6
it('should fail on falsiness', function() {
7
assert.ok(false);
8
});
9
10 });
11
12
13
14
15
16
$	
  mocha	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
groupedTests
groupSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  describe('with	
  a	
  subset	
  of	
  this	
  other	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  	
  	
  	
  	
  });
	
  	
  	
  	
  });
});
1 var expect = require('chai').expect;
2
3 describe('Assertions', function() {
describe('on equality', function() {
4
it('should pass on truthiness', function() {
5
expect(true).is.true;
6
});
7
it('should pass on falsiness', function() {
8
expect(false).is.false;
9
});
10
});
11
describe('on type', function() {
12
it('should pass on number', function() {
13
expect(5).is.a('number');
14
});
15
});
16
17 });
18
$	
  mocha	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  of	
  equality
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  falsiness	
  
	
  	
  	
  	
  on	
  type
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  number	
  

	
  	
  ✔	
  3	
  tests	
  complete	
  (6ms)
$	
  _
pendingTests
pendingSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  describe('with	
  a	
  subset	
  of	
  this	
  other	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  it('should	
  do	
  stuff	
  someday');
	
  	
  	
  	
  });
});
1 var assert = require('chai').assert;
2
3 describe('Assertions', function() {
describe('of truthiness', function() {
4
it('should pass on truthiness', function() {
5
expect(true).is.true;
6
});
7
it('should pass on falsiness', function() {
8
expect(false).is.false;
9
});
10
});
11
describe('of type', function() {
12
it('should pass on number', function() {
13
expect(5).is.a('number');
14
});
15
it('should pass on object');
16
});
17
18 });
$	
  mocha	
  -­‐-­‐reporter	
  spec

	
  	
  Assertions
	
  	
  	
  	
  of	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  falsiness
	
  	
  	
  	
  of	
  type
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  number	
  
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  object

	
  	
  ✔	
  4	
  tests	
  complete	
  (6ms)
	
  	
  •	
  1	
  test	
  pending
$	
  _
skippedTests
skipSyntax
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  it.skip('should	
  be	
  skipped',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
describe.skip('This	
  entire	
  suite	
  will	
  be	
  skipped',	
  function()	
  {
	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  });
});
1 describe('Assertions', function() {
describe('of truthiness', function() {
2
it('should pass on truthiness', function() {
3
assert.isTrue(true);
4
});
5
it('should pass on falsiness', function() {
6
assert.isFalse(false);
7
});
8
});
9
describe('of type', function() {
10
it.skip('should pass on number', function() {
11
assert.isNumber(5);
12
});
13
it('should pass on object');
14
});
15
16 });
17
18
$	
  make	
  test

	
  	
  Assertions
	
  	
  	
  	
  of	
  truthiness
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  falsiness	
  
	
  	
  	
  	
  of	
  type
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  number	
  
	
  	
  	
  	
  	
  	
  -­‐	
  should	
  pass	
  on	
  object

	
  	
  ✔	
  4	
  tests	
  complete	
  (6ms)
	
  	
  •	
  2	
  test	
  pending
$	
  _
setupTeardown
before();
beforeEach();
after();
afterEach();
setupTeardown
describe('Testing	
  out	
  this	
  thing',	
  function()	
  {
	
  	
  	
  	
  before(function(){
	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  };
	
  	
  	
  	
  describe('with	
  a	
  subset	
  of	
  that	
  thing',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  it('should	
  do	
  stuff',	
  function()	
  {
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  Assertion	
  tests
	
  	
  	
  	
  	
  	
  	
  	
  });
	
  	
  	
  	
  	
  	
  	
  	
  afterEach(function(){
	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  //	
  ...
	
  	
  	
  	
  	
  	
  	
  	
  };
	
  	
  	
  	
  });
});
asynchronousTests
asynchronousSyntax
it('should	
  not	
  error',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  done);
});
asynchronousSyntax
it('should	
  not	
  error',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  done);
});
it('should	
  return	
  2	
  items',	
  function(done)	
  {
	
  	
  	
  	
  search.find("Apples",	
  function(err,	
  res)	
  {
	
  	
  	
  	
  	
  	
  	
  	
  if	
  (err)	
  return	
  done(err);
	
  	
  	
  	
  	
  	
  	
  	
  res.should.have.length(2);
	
  	
  	
  	
  	
  	
  	
  	
  done();
	
  	
  	
  	
  });
});
All Mocha functions accept this callback
1 describe('When searching for Apples', function(done) {
before(function(done){
2
items.save(['fiji apples',
3
'empire apples'], done);
4
});
5
it('should not error', function(done) {
6
search.find("Apples", done);
7
});
8
it('should return 2 items', function(done) {
9
search.find("Apples", function(err, res) {
10
if (err) return done(err);
11
res.should.have.length(2);
12
done();
13
});
14
});
15
16 });
17
18
simplifyExecution
$	
  mocha	
  <args>

should be simplified to
$	
  make	
  test

and

$	
  npm	
  test
./makefile
1 # Makefile for sample module
2
3 test:
mocha --reporter spec --ui bdd
4
5
6
7
8 .PHONY: test
9
10
11
12
13
14
15
16
./makefile
1 # Makefile for sample module
2
3 test:
mocha 
4
--reporter spec 
5
--ui bdd
6
7
8 .PHONY: test
9
10
11
12
13
14
15
16
$	
  make	
  test

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
./package.json
1 {
"name": "sample",
2
"version": "0.1.0",
3
"scripts": {
4
"test": "make test"
5
}
6
7 }
8
9
10
11
12
13
14
15
16
$	
  npm	
  test

	
  	
  Assertions
	
  	
  	
  	
  ✓	
  should	
  pass	
  on	
  truthiness	
  
	
  	
  	
  	
  1)	
  should	
  fail	
  on	
  falsiness

	
  	
  ✖	
  1	
  of	
  2	
  tests	
  failed:
	
  	
  1)	
  Assertions	
  should	
  fail	
  on	
  falsiness:
	
  	
  	
  	
  	
  
	
  	
  AssertionError:	
  false	
  ==	
  true
	
  	
  	
  	
  	
  	
  at	
  (stack	
  trace	
  omitted	
  for	
  brevity)
$	
  _
eliminate global dependency
$	
  npm	
  install	
  mocha	
  -­‐-­‐link
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec 
3
--ui bdd
4
5
6 .PHONY: test
7
8
9
10
11
12
13
14
15
16
17
18
update dev dependencies
$	
  npm	
  install	
  mocha	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  chai	
  	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  mocha	
  -­‐-­‐save-­‐dev
$	
  npm	
  install	
  chai	
  	
  -­‐-­‐save-­‐dev
$	
  git	
  diff	
  package.json	
  
diff	
  -­‐-­‐git	
  a/package.json	
  b/package.json
index	
  439cf44..3609bb9	
  100644
-­‐-­‐-­‐	
  a/package.json
+++	
  b/package.json
@@	
  -­‐1,5	
  +1,7	
  @@
	
  {
	
  	
  	
  "name":	
  "sample",
-­‐	
  	
  "version":	
  "0.1.0"
+	
  	
  "version":	
  "0.1.0",
+	
  	
  "devDependencies":	
  {
+	
  	
  	
  	
  "mocha":	
  "~1.9.0",
+	
  	
  	
  	
  "chai":	
  "~1.6.0"
+	
  	
  }
	
  }
notificationSystems
continuousTesting
mocha --watch
-w or --watch
$	
  mocha	
  -­‐-­‐watch

	
  ✔	
  5	
  tests	
  complete	
  (22ms)
	
  ^	
  watching
Growl
mac: apple app store
win: growlForWindows.com
also: growlNotify
growlNotifications
mocha --growl
-G or --growl
⌘S
1 test:
@./node_modules/.bin/mocha 
2
--reporter spec 
3
--ui bdd
4
5
6 watch:
@./node_modules/.bin/mocha 
7
--reporter min 
8
--ui bdd 
9
--growl 
10
--watch
11
12
13 .PHONY: test watch
14
15
16
17
18
mockingObjects
JavaScript ships with a mocking framework
...it’s called JavaScript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var me = {firstName: 'Jay'
, lastName: 'Harris'
, getFullName: function() {
return this.firstName +
' ' +
this.lastName; }};
// Returns 'Jay Harris'
me.getFullName();
me.getFullName = function() { return 'John Doe'; };
// Returns 'John Doe'
me.getFullName();
nock

HTTP Mocking Library
nock

github: flatiron/nock
install: npm install nock
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var http = require('http');
var reqOptions = {
host: 'api.twitter.com',
path: '/1/statuses/user_timeline.json?' +
'screen_name=jayharris'
};
// ...
http.request(reqOptions, resCallback).end();
// Returns live Twitter data
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

var nock = require('nock');
var twitter = nock('http://api.twitter.com')
.get('/1/statuses/user_timeline.json?'+
'screen_name=jayharris')
.reply(200, "This worked");
// Returns "This worked"
http.request(reqOptions, resCallback).end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

// Returns live Twitter data
http.request(reqOptions, resCallback).end();
var nock = require('nock');
var twitter = nock('http://api.twitter.com')
.get('/1/statuses/user_timeline.json?'+
'screen_name=jayharris')
.reply(200, "This worked");
// Returns "This worked"
http.request(reqOptions, resCallback).end();
// Returns live Twitter data
http.request(reqOptions, resCallback).end();
nock

nock.recorder.rec(	
  );
nock.recorder.play(	
  );
Sinon.js

Spies, Stubs, & Mocks
Sinon.js

github: cjohansen/Sinon.JS
install: npm install sinon
versionTesting
nvm

Node Version Manager
nvm

github: creationix/nvm
github: hakobera/nvmw
$	
  nvm	
  list
	
  	
  	
  	
  v0.4.0	
  	
  	
  	
  v0.6.18	
  	
  	
  	
  v0.8.21
	
  	
  	
  	
  v0.4.7	
  	
  	
  	
  	
  v0.8.1	
  	
  	
  	
  v0.10.0
	
  	
  	
  	
  v0.6.0	
  	
  	
  	
  	
  v0.8.8
current:	
  	
  
v0.8.1
10	
  -­‐>	
  0.10.0	
  (-­‐>	
  v0.10.0)
4	
  -­‐>	
  0.4.7	
  (-­‐>	
  v0.4.7)
6	
  -­‐>	
  0.6.18	
  (-­‐>	
  v0.6.18)
8	
  -­‐>	
  0.8.21	
  (-­‐>	
  v0.8.21)
default	
  -­‐>	
  0.10.0	
  (-­‐>	
  v0.10.0)
newest	
  -­‐>	
  0.10.0	
  (-­‐>	
  v0.10.0)
$	
  _
$	
  node	
  -­‐-­‐version
v0.10.0
$	
  nvm	
  install	
  v0.10.6
Now	
  using	
  node	
  v0.10.6
/Users/jayharris/.nvm/v0.10.6/bin/npm
$	
  node	
  -­‐-­‐version
v0.10.6
$	
  _
packageDistribution
Package Manager
filePackaging
./.npmignore
userSetup
npm adduser
$	
  npm	
  adduser
Username:	
  (jayharris)	
  jayharris
Password:
Email:	
  (jay@aranasoft.com)	
  _
$	
  npm	
  whoami
jayharris
$	
  _
packagePublish
npm publish
{	
  name:	
  'morale',
	
  	
  description:	
  'Async	
  API	
  wrapper	
  for	
  Morale',
	
  	
  'dist-­‐tags':	
  {	
  latest:	
  '0.2.0'	
  },
	
  	
  versions:	
  
	
  	
  	
  [	
  '0.1.0',
	
  	
  	
  	
  	
  '0.1.2',
	
  	
  	
  	
  	
  '0.2.0'	
  ],
	
  	
  maintainers:	
  'jayharris	
  <jay@aranasoft.com>',
	
  	
  time:	
  
	
  	
  	
  {	
  '0.1.0':	
  '2012-­‐01-­‐23T03:24:59.824Z',
	
  	
  	
  	
  	
  '0.1.2':	
  '2012-­‐01-­‐25T23:20:52.927Z',
	
  	
  	
  	
  	
  '0.2.0':	
  '2012-­‐08-­‐13T16:23:28.488Z'	
  },
	
  	
  author:	
  'Arana	
  Software	
  <info@aranasoft.com>',
	
  	
  repository:	
  
	
  	
  	
  {	
  type:	
  'git',
	
  	
  	
  	
  	
  url:	
  'git://github.com/aranasoft/morale-­‐node.git'	
  },
	
  	
  users:	
  {	
  fgribreau:	
  true	
  },
	
  	
  version:	
  '0.2.0',
$	
  npm	
  publish
npm	
  http	
  PUT	
  https://registry.npmjs.org/morale
npm	
  http	
  409	
  https://registry.npmjs.org/morale
npm	
  http	
  GET	
  https://registry.npmjs.org/morale
npm	
  http	
  200	
  https://registry.npmjs.org/morale
npm	
  http	
  PUT	
  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest
npm	
  http	
  201	
  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest
npm	
  http	
  GET	
  https://registry.npmjs.org/morale
npm	
  http	
  200	
  https://registry.npmjs.org/morale
npm	
  http	
  PUT	
  https://registry.npmjs.org/morale/-­‐/
morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b
npm	
  http	
  201	
  https://registry.npmjs.org/morale/-­‐/
morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b
+	
  morale@0.2.1
$	
  _
{	
  name:	
  'morale',
	
  	
  description:	
  'Async	
  API	
  wrapper	
  for	
  Morale',
	
  	
  'dist-­‐tags':	
  {	
  latest:	
  '0.2.1'	
  },
	
  	
  versions:	
  
	
  	
  	
  [	
  '0.1.0',
	
  	
  	
  	
  	
  '0.1.2',
	
  	
  	
  	
  	
  '0.2.0',
	
  	
  	
  	
  	
  '0.2.1'	
  ],
	
  	
  maintainers:	
  'jayharris	
  <jay@aranasoft.com>',
	
  	
  time:	
  
	
  	
  	
  {	
  '0.1.0':	
  '2012-­‐01-­‐23T03:24:59.824Z',
	
  	
  	
  	
  	
  '0.1.2':	
  '2012-­‐01-­‐25T23:20:52.927Z',
	
  	
  	
  	
  	
  '0.2.0':	
  '2012-­‐08-­‐13T16:23:28.488Z',
	
  	
  	
  	
  	
  '0.2.1':	
  '2012-­‐08-­‐30T19:10:20.133Z'	
  },
	
  	
  author:	
  'Arana	
  Software	
  <info@aranasoft.com>',
	
  	
  repository:	
  
	
  	
  	
  {	
  type:	
  'git',
	
  	
  	
  	
  	
  url:	
  'git://github.com/aranasoft/morale-­‐node.git'	
  },
privatePackages
{ "private": "true" }
./package.json
1 {
"name": "Sample",
2
"version": "0.1.0",
3
"description": "This is a sample module",
4
"main": "index.js",
5
"scripts": {
6
"test": "echo "Error: no tests avail." && exit 1"
7
},
8
"author": "Jay Harris",
9
"license": "BSD",
10
"private": "true"
11
12 }
13
14
15
16
$	
  npm	
  publish
npm	
  ERR!	
  Error:	
  This	
  package	
  has	
  been	
  marked	
  as	
  private
npm	
  ERR!	
  Remove	
  the	
  'private'	
  field	
  from	
  the	
  package.json	
  to	
  
publish	
  it.
$	
  _
versionLockdown
npm shrinkwrap
$	
  npm	
  shrinkwrap
wrote	
  npm-­‐shrinkwrap.json
$	
  _
1 {
"name": "morale",
2
"version": "0.2.1",
3
"dependencies": {
4
"underscore": {
5
"version": "1.3.3"
6
},
7
"mocha": {
8
"version": "1.3.0",
9
"dependencies": {
10
"commander": {
11
"version": "0.6.1"
12
},
13
"growl": {
14
"version": "1.5.1"
15
},
16
"jade": {
17
"version": "0.26.3",
18
$	
  rm	
  npm-­‐shrinkwrap.json
$	
  npm	
  update
$	
  npm	
  test
$	
  npm	
  shrinkwrap
tellEveryone
Go make some Awesome
jay harris

P R E S I D E N T

jay@aranasoft.com
#nodemoduledev
@jayharris

Contenu connexe

Tendances

The report of JavaOne2011 about groovy
The report of JavaOne2011 about groovyThe report of JavaOne2011 about groovy
The report of JavaOne2011 about groovyYasuharu Nakano
 
Understanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsUnderstanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsShinpei Hayashi
 
¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?jaespinmora
 
Modern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlModern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlNova Patch
 
C++ Programming - 9th Study
C++ Programming - 9th StudyC++ Programming - 9th Study
C++ Programming - 9th StudyChris Ohk
 
C++ Programming - 12th Study
C++ Programming - 12th StudyC++ Programming - 12th Study
C++ Programming - 12th StudyChris Ohk
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersIan Barber
 
Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsYandex
 
JavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, MoscowJavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, MoscowRobert Nyman
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)guregu
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Kenji Tanaka
 
Haskell is Not For Production and Other Tales
Haskell is Not For Production and Other TalesHaskell is Not For Production and Other Tales
Haskell is Not For Production and Other TalesKatie Ots
 

Tendances (20)

The report of JavaOne2011 about groovy
The report of JavaOne2011 about groovyThe report of JavaOne2011 about groovy
The report of JavaOne2011 about groovy
 
Deep dive into Oracle ADF
Deep dive into Oracle ADFDeep dive into Oracle ADF
Deep dive into Oracle ADF
 
Understanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring EffectsUnderstanding Source Code Differences by Separating Refactoring Effects
Understanding Source Code Differences by Separating Refactoring Effects
 
Testing with Node.js
Testing with Node.jsTesting with Node.js
Testing with Node.js
 
¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?
 
Modern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlModern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in Perl
 
C++ Programming - 9th Study
C++ Programming - 9th StudyC++ Programming - 9th Study
C++ Programming - 9th Study
 
C++ Programming - 12th Study
C++ Programming - 12th StudyC++ Programming - 12th Study
C++ Programming - 12th Study
 
Teaching Your Machine To Find Fraudsters
Teaching Your Machine To Find FraudstersTeaching Your Machine To Find Fraudsters
Teaching Your Machine To Find Fraudsters
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
Всеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.jsВсеволод Струкчинский: Node.js
Всеволод Струкчинский: Node.js
 
JavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, MoscowJavaScript APIs - The Web is the Platform - .toster conference, Moscow
JavaScript APIs - The Web is the Platform - .toster conference, Moscow
 
神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)神に近づくx/net/context (Finding God with x/net/context)
神に近づくx/net/context (Finding God with x/net/context)
 
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -Stubる - Mockingjayを使ったHTTPクライアントのテスト -
Stubる - Mockingjayを使ったHTTPクライアントのテスト -
 
Perl Web Client
Perl Web ClientPerl Web Client
Perl Web Client
 
PHP 5.4
PHP 5.4PHP 5.4
PHP 5.4
 
Con5623 pdf 5623_001
Con5623 pdf 5623_001Con5623 pdf 5623_001
Con5623 pdf 5623_001
 
Node.js 0.8 features
Node.js 0.8 featuresNode.js 0.8 features
Node.js 0.8 features
 
Haskell is Not For Production and Other Tales
Haskell is Not For Production and Other TalesHaskell is Not For Production and Other Tales
Haskell is Not For Production and Other Tales
 

En vedette

наталинци 3
наталинци 3наталинци 3
наталинци 3givenchy1
 
pUBLICIDAD EN REDES SOCIALES
pUBLICIDAD EN REDES SOCIALESpUBLICIDAD EN REDES SOCIALES
pUBLICIDAD EN REDES SOCIALESChris Burguette
 
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
#rumboajapon2015 Alex Salazar 2 evidencias de EmprenderUrban Gent
 
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in DesignUCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in DesignStephen Denning
 
Riesgo de la automedicación y tratamientos alternativos.
Riesgo de la automedicación y tratamientos alternativos.Riesgo de la automedicación y tratamientos alternativos.
Riesgo de la automedicación y tratamientos alternativos.Miguel Sánchez Pérez
 
Recomanacions estiu2016 biblioteca
Recomanacions estiu2016 bibliotecaRecomanacions estiu2016 biblioteca
Recomanacions estiu2016 bibliotecalluís nater
 
DEV208 - ASP.NET MVC 5 新功能探索
DEV208 - ASP.NET MVC 5 新功能探索DEV208 - ASP.NET MVC 5 新功能探索
DEV208 - ASP.NET MVC 5 新功能探索Will Huang
 
Sepsis y trombocitopenia immune. Caso Clínico Terapéutico
Sepsis y trombocitopenia immune. Caso Clínico TerapéuticoSepsis y trombocitopenia immune. Caso Clínico Terapéutico
Sepsis y trombocitopenia immune. Caso Clínico Terapéuticoevidenciaterapeutica.com
 
Y6 华文 单元 4 习写作文
Y6 华文 单元 4 习写作文 Y6 华文 单元 4 习写作文
Y6 华文 单元 4 习写作文 慈心 Chan
 

En vedette (14)

Nota informativa sobre contaminación luminosa
Nota informativa sobre contaminación luminosaNota informativa sobre contaminación luminosa
Nota informativa sobre contaminación luminosa
 
наталинци 3
наталинци 3наталинци 3
наталинци 3
 
pUBLICIDAD EN REDES SOCIALES
pUBLICIDAD EN REDES SOCIALESpUBLICIDAD EN REDES SOCIALES
pUBLICIDAD EN REDES SOCIALES
 
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
#rumboajapon2015 Alex Salazar 2 evidencias de Emprender
 
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in DesignUCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
UCD 2013 - Shapes & Patterns: The Role of Pre-Attentive Psychology in Design
 
Objetivos bloom
Objetivos bloomObjetivos bloom
Objetivos bloom
 
Riesgo de la automedicación y tratamientos alternativos.
Riesgo de la automedicación y tratamientos alternativos.Riesgo de la automedicación y tratamientos alternativos.
Riesgo de la automedicación y tratamientos alternativos.
 
Recomanacions estiu2016 biblioteca
Recomanacions estiu2016 bibliotecaRecomanacions estiu2016 biblioteca
Recomanacions estiu2016 biblioteca
 
Pipe Laying Barge
Pipe Laying BargePipe Laying Barge
Pipe Laying Barge
 
DEV208 - ASP.NET MVC 5 新功能探索
DEV208 - ASP.NET MVC 5 新功能探索DEV208 - ASP.NET MVC 5 新功能探索
DEV208 - ASP.NET MVC 5 新功能探索
 
Thematic Analysis
Thematic AnalysisThematic Analysis
Thematic Analysis
 
Graphic aids (2)
Graphic aids (2)Graphic aids (2)
Graphic aids (2)
 
Sepsis y trombocitopenia immune. Caso Clínico Terapéutico
Sepsis y trombocitopenia immune. Caso Clínico TerapéuticoSepsis y trombocitopenia immune. Caso Clínico Terapéutico
Sepsis y trombocitopenia immune. Caso Clínico Terapéutico
 
Y6 华文 单元 4 习写作文
Y6 华文 单元 4 习写作文 Y6 华文 单元 4 习写作文
Y6 华文 单元 4 习写作文
 

Similaire à node.js Module Development

UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013Michelangelo van Dam
 
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQUA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQMichelangelo van Dam
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with JestMichał Pierzchała
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013Michelangelo van Dam
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013Michelangelo van Dam
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QAarchwisp
 
NodeJs
NodeJsNodeJs
NodeJsdizabl
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesAnkit Rastogi
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Tsuyoshi Yamamoto
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitsmueller_sandsmedia
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and youmarkstory
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboardsDenis Ristic
 

Similaire à node.js Module Development (20)

Fatc
FatcFatc
Fatc
 
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
UA testing with Selenium and PHPUnit - TrueNorthPHP 2013
 
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQUA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
UA testing with Selenium and PHPUnit - PHPBenelux Summer BBQ
 
Painless JavaScript Testing with Jest
Painless JavaScript Testing with JestPainless JavaScript Testing with Jest
Painless JavaScript Testing with Jest
 
UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013UA testing with Selenium and PHPUnit - PFCongres 2013
UA testing with Selenium and PHPUnit - PFCongres 2013
 
UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013UA Testing with Selenium and PHPUnit - ZendCon 2013
UA Testing with Selenium and PHPUnit - ZendCon 2013
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Vagrant for real
Vagrant for realVagrant for real
Vagrant for real
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QACreating "Secure" PHP Applications, Part 1, Explicit Code & QA
Creating "Secure" PHP Applications, Part 1, Explicit Code & QA
 
NodeJs
NodeJsNodeJs
NodeJs
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Ten useful JavaScript tips & best practices
Ten useful JavaScript tips & best practicesTen useful JavaScript tips & best practices
Ten useful JavaScript tips & best practices
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnitinternational PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
international PHP2011_Bastian Feder_The most unknown Parts of PHPUnit
 
PHPunit and you
PHPunit and youPHPunit and you
PHPunit and you
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards
 
Test innode
Test innodeTest innode
Test innode
 

Plus de Jay Harris

Bullets Kill People: Building Effective Presentations
Bullets Kill People: Building Effective PresentationsBullets Kill People: Building Effective Presentations
Bullets Kill People: Building Effective PresentationsJay Harris
 
Dethroning Grunt: Simple and Effective Builds with gulp.js
Dethroning Grunt: Simple and Effective Builds with gulp.jsDethroning Grunt: Simple and Effective Builds with gulp.js
Dethroning Grunt: Simple and Effective Builds with gulp.jsJay Harris
 
OrchardCMS module development
OrchardCMS module developmentOrchardCMS module development
OrchardCMS module developmentJay Harris
 
The Geek's Guide to SEO
The Geek's Guide to SEOThe Geek's Guide to SEO
The Geek's Guide to SEOJay Harris
 
Going for Speed: Testing for Performance
Going for Speed: Testing for PerformanceGoing for Speed: Testing for Performance
Going for Speed: Testing for PerformanceJay Harris
 
Dev Basics: The ASP.NET Page Life Cycle
Dev Basics: The ASP.NET Page Life CycleDev Basics: The ASP.NET Page Life Cycle
Dev Basics: The ASP.NET Page Life CycleJay Harris
 

Plus de Jay Harris (6)

Bullets Kill People: Building Effective Presentations
Bullets Kill People: Building Effective PresentationsBullets Kill People: Building Effective Presentations
Bullets Kill People: Building Effective Presentations
 
Dethroning Grunt: Simple and Effective Builds with gulp.js
Dethroning Grunt: Simple and Effective Builds with gulp.jsDethroning Grunt: Simple and Effective Builds with gulp.js
Dethroning Grunt: Simple and Effective Builds with gulp.js
 
OrchardCMS module development
OrchardCMS module developmentOrchardCMS module development
OrchardCMS module development
 
The Geek's Guide to SEO
The Geek's Guide to SEOThe Geek's Guide to SEO
The Geek's Guide to SEO
 
Going for Speed: Testing for Performance
Going for Speed: Testing for PerformanceGoing for Speed: Testing for Performance
Going for Speed: Testing for Performance
 
Dev Basics: The ASP.NET Page Life Cycle
Dev Basics: The ASP.NET Page Life CycleDev Basics: The ASP.NET Page Life Cycle
Dev Basics: The ASP.NET Page Life Cycle
 

Dernier

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 

Dernier (20)

08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
Transcript: #StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 

node.js Module Development

  • 2. What is node.js? “ Node.js is a platform built on Chrome's JavaScript runtime for easily building fast, scalable network applications. ”
  • 3.
  • 4. ./
  • 16. globalInstallation npm install <package> --global -g or --global
  • 18. dependencyReferences npm install <package> --save[-dev] --save or --save-dev
  • 21. $  npm  init name: (sample-node) Sample version: (0.0.0) 0.1.0 description: This is a sample module entry point: (index.js) _
  • 22. author:  Jay  Harris license:  (BSD)  BSD About  to  write  to  /Projects/sample-­‐node/package.json: {    "name":  "Sample",    "version":  "0.1.0",    "description":  "This  is  a  sample  module",    "main":  "index.js",    "scripts":  {        "test":  "echo  "Error:  no  test  specified"  &&  exit  1"    },    "author":  "Jay  Harris",    "license":  "BSD" } Is  this  ok?  (yes)  _
  • 23. ./package.json 1 { "name": "Sample", 2 "version": "0.1.0", 3 "description": "This is a sample module", 4 "main": "index.js", 5 "scripts": { 6 "test": "echo "Error: no tests avail." && exit 1" 7 }, 8 "author": "Jay Harris", 9 "license": "BSD" 10 11 } 12 13 14 15 16
  • 24. npm init is additive not destructive
  • 28. ./lib/sample.js 1 module.exports.sayHello = function() { return "Hello World!"; 2 3 } 4 5 6 7 8 9 10 11 12 13 14 15 16
  • 29. var  sample  =  require("./lib/sample.js"); //  Returns  'Hello  World!' sample.sayHello();
  • 30. ./lib/person.js 1 function Person(first, last) { if (!(this instanceof Person)) { 2 return new Person(first, last); 3 } 4 5 this.firstName = first; 6 this.lastName = last; 7 8 return this; 9 10 } 11 12 module.exports = Person; 13 14 15 16
  • 31. var person = require("./lib/person.js"); // This will return undefined person.firstName; // This will return 'Jay' var jayHarris = new Person('Jay','Harris'); jayHarris.firstName;
  • 32. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function Person(first, last) { // ... } module.exports = Person; // This is a public method; Person.prototype.sayHello = function() { return _join.call(this, "Hello", this.firstName); } // This is a private method var _join(first, second) { return first + ' ' + second; }
  • 33. var  person  =  require("./lib/person.js"); //  This  will  throw  'Has  No  Method'  error person.sayHello(); //  This  will  return  'Hello  Jay' var  jayHarris  =  new  Person('Jay','Harris'); jayHarris.sayHello();
  • 34. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function Person(first, last) { // ... } module.exports = Person; // This is a static method module.exports.sayHello = function() { return "Hello World!"; } // This is a public instance method; Person.prototype.sayHello = function() { return _join.call(this, "Hello", this.firstName); } // This is a private method var _join(first, second) { return first + ' ' + second; }
  • 35. var  person  =  require("./lib/person.js"); //  This  will  return  'Hello  World!' person.sayHello(); //  This  will  return  'Hello  Jay' var  jayHarris  =  new  Person('Jay','Harris'); jayHarris.sayHello();
  • 37. var  EventEmitter  =  require('events').EventEmitter;
  • 39. var  util  =  require('util'); //  ... util.inherits(MyClass,  EventEmitter);
  • 40. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var EventEmitter = require('events').EventEmitter , util = require('util'); function Person(first, last) { // ... EventEmitter.call(this); // ... } util.inherits(Person, EventEmitter); Person.prototype.goToBed = function() { this.emit("sleep"); }
  • 41. var  person  =  require("./person.js"); //  This  will  return  'Hello  Jay' var  jayHarris  =  new  Person('Jay','Harris'); jayHarris.on("sleep",  function()  {        console.log("Goodnight,  Jay"); } jayHarris.goToBed(); //  Output  'Goodnight,  Jay'
  • 43. “ TDD is to coding style as yoga is to posture. Even when you're not actively practicing, having done so colors your whole life healthier. ” j. kerr
  • 45. var  assert  =  require('assert');
  • 46. assert(value)            .ok(value)            .equal(actual,  expected)            .notEqual(actual,  expected)            .deepEqual(actual,  expected)            .notDeepEqual(actual,  expected)            .strictEqual(actual,  expected)            .notStrictEqual(actual,  expected)            .throws(block,  [error])            .doesNotThrow(block,  [error])            .ifError(value)
  • 47. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var assert = require('assert'); // Will pass assert.ok(true); // Will throw an exception assert.ok(false);
  • 48. 1 var assert = require('assert'); 2 3 // Will throw 'false == true' error 4 assert.ok(typeof 'hello' === 'number'); 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  • 49. $  node  test.js assert.js:104    throw  new  assert.AssertionError({                ^ AssertionError:  false  ==  true        at  Object.<anonymous>  (my-­‐test.js:7:8)        at  Module._compile  (module.js:449:26)        at  Object.Module._extensions..js  (module.js:467:10)        at  Module.load  (module.js:356:32)        at  Function.Module._load  (module.js:312:12)        at  Module.runMain  (module.js:487:10)        at  process.startup.processNextTick.process._tick... $  _
  • 52. isTrue,                      isFalse, isNull,                      isNotNull, isUndefined,            isDefined, isFunction,              isNotFunction, isArray,                    isNotArray, isBoolean,                isNotBoolean, isNumber,                  isNotNumber, isString,                  isNotString,                                    include,                                    lengthOf,                                    operator,                                    closeTo   isObject,                  isNotObject, typeOf,                      notTypeOf, instanceOf,              notInstanceOf, match,                        notMatch, property,                  notProperty, deepProperty,          notDeepProperty, propertyVal,            propertyNotVal, deepPropertyVal,    deepPropertyNotVal, additional assertions
  • 53. var  assert  =  require('chai').assert;
  • 54. 1 var assert = require('chai').assert; 2 3 // Will throw 'expected 'hello' to be a number' 4 assert.isNumber('hello'); 5 6 7 8 9 10 11 12 13 14 15 16 17 18
  • 55. $  node  test.js expected  'hello'  to  be  a  number $  _
  • 56. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var chai = require('chai') , assert = chai.assert; chai.Assertion.includeStack = true; // Will throw and display stack assert.isNumber('hello');
  • 59. var  expect  =  require('chai').expect;
  • 61. expect(person).to.exist        .and.be.an('object')        .with.property('age')        .that.is.to.exist        .and.is.a('number')        .and.equals(34);
  • 63. expect(person).to.exist        .and.be.an('object')        .with.property('age')        .that.is.to.exist        .and.is.a('number')        .and.equals(34);
  • 64. expect(person).to.exist        .and.be.an('object')        .with.property('age')        .that.is.to.exist        .and.is.a('number')        .and.equals(34);
  • 66. expect(person)    .that.is.an('object')    .with.property('address')        .that.is.an('object')        .with.property('city')            .that.is.a('string')            .and.equals('Detroit')
  • 70. $  npm  install  -­‐g  mocha $  mkdir  test $  mocha        ✔  0  tests  complete  (1ms) $  
  • 71. var  mocha  =  require('mocha');
  • 72. bddSyntax describe('Testing  out  this  thing',  function()  {        it('should  do  stuff',  function()  {                //  Assertion  tests        }); });
  • 73. ./test/my-test.js 1 var assert = require('assert'); 2 3 describe('Assertions', function() { it('should pass on truthiness', function() { 4 assert.ok(true); 5 }); 6 it('should fail on falsiness', function() { 7 assert.ok(false); 8 }); 9 10 }); 11 12 13 14 15 16
  • 74. $  mocha  -­‐-­‐reporter  spec    Assertions        ✓  should  pass  on  truthiness          1)  should  fail  on  falsiness    ✖  1  of  2  tests  failed:    1)  Assertions  should  fail  on  falsiness:              AssertionError:  false  ==  true            at  (stack  trace  omitted  for  brevity) $  _
  • 76. groupSyntax describe('Testing  out  this  thing',  function()  {        describe('with  a  subset  of  this  other  thing',  function()  {                it('should  do  stuff',  function()  {                        //  Assertion  tests                });        }); });
  • 77. 1 var expect = require('chai').expect; 2 3 describe('Assertions', function() { describe('on equality', function() { 4 it('should pass on truthiness', function() { 5 expect(true).is.true; 6 }); 7 it('should pass on falsiness', function() { 8 expect(false).is.false; 9 }); 10 }); 11 describe('on type', function() { 12 it('should pass on number', function() { 13 expect(5).is.a('number'); 14 }); 15 }); 16 17 }); 18
  • 78. $  mocha  -­‐-­‐reporter  spec    Assertions        of  equality            ✓  should  pass  on  truthiness              ✓  should  pass  on  falsiness          on  type            ✓  should  pass  on  number      ✔  3  tests  complete  (6ms) $  _
  • 80. pendingSyntax describe('Testing  out  this  thing',  function()  {        describe('with  a  subset  of  this  other  thing',  function()  {                it('should  do  stuff  someday');        }); });
  • 81. 1 var assert = require('chai').assert; 2 3 describe('Assertions', function() { describe('of truthiness', function() { 4 it('should pass on truthiness', function() { 5 expect(true).is.true; 6 }); 7 it('should pass on falsiness', function() { 8 expect(false).is.false; 9 }); 10 }); 11 describe('of type', function() { 12 it('should pass on number', function() { 13 expect(5).is.a('number'); 14 }); 15 it('should pass on object'); 16 }); 17 18 });
  • 82. $  mocha  -­‐-­‐reporter  spec    Assertions        of  truthiness            ✓  should  pass  on  truthiness            ✓  should  pass  on  falsiness        of  type            ✓  should  pass  on  number              -­‐  should  pass  on  object    ✔  4  tests  complete  (6ms)    •  1  test  pending $  _
  • 84. skipSyntax describe('Testing  out  this  thing',  function()  {        it.skip('should  be  skipped',  function()  {                //  Assertion  tests        }); }); describe.skip('This  entire  suite  will  be  skipped',  function()  {        it('should  do  stuff',  function()  {                //  Assertion  tests        }); });
  • 85. 1 describe('Assertions', function() { describe('of truthiness', function() { 2 it('should pass on truthiness', function() { 3 assert.isTrue(true); 4 }); 5 it('should pass on falsiness', function() { 6 assert.isFalse(false); 7 }); 8 }); 9 describe('of type', function() { 10 it.skip('should pass on number', function() { 11 assert.isNumber(5); 12 }); 13 it('should pass on object'); 14 }); 15 16 }); 17 18
  • 86. $  make  test    Assertions        of  truthiness            ✓  should  pass  on  truthiness              ✓  should  pass  on  falsiness          of  type            -­‐  should  pass  on  number              -­‐  should  pass  on  object    ✔  4  tests  complete  (6ms)    •  2  test  pending $  _
  • 89. setupTeardown describe('Testing  out  this  thing',  function()  {        before(function(){                //  ...        };        describe('with  a  subset  of  that  thing',  function()  {                it('should  do  stuff',  function()  {                        //  Assertion  tests                });                afterEach(function(){                        //  ...                };        }); });
  • 91. asynchronousSyntax it('should  not  error',  function(done)  {        search.find("Apples",  done); });
  • 92. asynchronousSyntax it('should  not  error',  function(done)  {        search.find("Apples",  done); }); it('should  return  2  items',  function(done)  {        search.find("Apples",  function(err,  res)  {                if  (err)  return  done(err);                res.should.have.length(2);                done();        }); });
  • 93. All Mocha functions accept this callback
  • 94. 1 describe('When searching for Apples', function(done) { before(function(done){ 2 items.save(['fiji apples', 3 'empire apples'], done); 4 }); 5 it('should not error', function(done) { 6 search.find("Apples", done); 7 }); 8 it('should return 2 items', function(done) { 9 search.find("Apples", function(err, res) { 10 if (err) return done(err); 11 res.should.have.length(2); 12 done(); 13 }); 14 }); 15 16 }); 17 18
  • 96. $  mocha  <args> should be simplified to $  make  test and $  npm  test
  • 97. ./makefile 1 # Makefile for sample module 2 3 test: mocha --reporter spec --ui bdd 4 5 6 7 8 .PHONY: test 9 10 11 12 13 14 15 16
  • 98. ./makefile 1 # Makefile for sample module 2 3 test: mocha 4 --reporter spec 5 --ui bdd 6 7 8 .PHONY: test 9 10 11 12 13 14 15 16
  • 99. $  make  test    Assertions        ✓  should  pass  on  truthiness          1)  should  fail  on  falsiness    ✖  1  of  2  tests  failed:    1)  Assertions  should  fail  on  falsiness:              AssertionError:  false  ==  true            at  (stack  trace  omitted  for  brevity) $  _
  • 100. ./package.json 1 { "name": "sample", 2 "version": "0.1.0", 3 "scripts": { 4 "test": "make test" 5 } 6 7 } 8 9 10 11 12 13 14 15 16
  • 101. $  npm  test    Assertions        ✓  should  pass  on  truthiness          1)  should  fail  on  falsiness    ✖  1  of  2  tests  failed:    1)  Assertions  should  fail  on  falsiness:              AssertionError:  false  ==  true            at  (stack  trace  omitted  for  brevity) $  _
  • 102. eliminate global dependency $  npm  install  mocha  -­‐-­‐link
  • 103. 1 test: @./node_modules/.bin/mocha 2 --reporter spec 3 --ui bdd 4 5 6 .PHONY: test 7 8 9 10 11 12 13 14 15 16 17 18
  • 104. update dev dependencies $  npm  install  mocha  -­‐-­‐save-­‐dev $  npm  install  chai    -­‐-­‐save-­‐dev
  • 105. $  npm  install  mocha  -­‐-­‐save-­‐dev $  npm  install  chai    -­‐-­‐save-­‐dev $  git  diff  package.json   diff  -­‐-­‐git  a/package.json  b/package.json index  439cf44..3609bb9  100644 -­‐-­‐-­‐  a/package.json +++  b/package.json @@  -­‐1,5  +1,7  @@  {      "name":  "sample", -­‐    "version":  "0.1.0" +    "version":  "0.1.0", +    "devDependencies":  { +        "mocha":  "~1.9.0", +        "chai":  "~1.6.0" +    }  }
  • 108. $  mocha  -­‐-­‐watch  ✔  5  tests  complete  (22ms)  ^  watching
  • 109. Growl
  • 110. mac: apple app store win: growlForWindows.com also: growlNotify
  • 112. ⌘S
  • 113. 1 test: @./node_modules/.bin/mocha 2 --reporter spec 3 --ui bdd 4 5 6 watch: @./node_modules/.bin/mocha 7 --reporter min 8 --ui bdd 9 --growl 10 --watch 11 12 13 .PHONY: test watch 14 15 16 17 18
  • 115. JavaScript ships with a mocking framework ...it’s called JavaScript
  • 116. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var me = {firstName: 'Jay' , lastName: 'Harris' , getFullName: function() { return this.firstName + ' ' + this.lastName; }}; // Returns 'Jay Harris' me.getFullName(); me.getFullName = function() { return 'John Doe'; }; // Returns 'John Doe' me.getFullName();
  • 119. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var http = require('http'); var reqOptions = { host: 'api.twitter.com', path: '/1/statuses/user_timeline.json?' + 'screen_name=jayharris' }; // ... http.request(reqOptions, resCallback).end(); // Returns live Twitter data
  • 120. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 var nock = require('nock'); var twitter = nock('http://api.twitter.com') .get('/1/statuses/user_timeline.json?'+ 'screen_name=jayharris') .reply(200, "This worked"); // Returns "This worked" http.request(reqOptions, resCallback).end();
  • 121. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Returns live Twitter data http.request(reqOptions, resCallback).end(); var nock = require('nock'); var twitter = nock('http://api.twitter.com') .get('/1/statuses/user_timeline.json?'+ 'screen_name=jayharris') .reply(200, "This worked"); // Returns "This worked" http.request(reqOptions, resCallback).end(); // Returns live Twitter data http.request(reqOptions, resCallback).end();
  • 128. $  nvm  list        v0.4.0        v0.6.18        v0.8.21        v0.4.7          v0.8.1        v0.10.0        v0.6.0          v0.8.8 current:     v0.8.1 10  -­‐>  0.10.0  (-­‐>  v0.10.0) 4  -­‐>  0.4.7  (-­‐>  v0.4.7) 6  -­‐>  0.6.18  (-­‐>  v0.6.18) 8  -­‐>  0.8.21  (-­‐>  v0.8.21) default  -­‐>  0.10.0  (-­‐>  v0.10.0) newest  -­‐>  0.10.0  (-­‐>  v0.10.0) $  _
  • 129. $  node  -­‐-­‐version v0.10.0 $  nvm  install  v0.10.6 Now  using  node  v0.10.6 /Users/jayharris/.nvm/v0.10.6/bin/npm $  node  -­‐-­‐version v0.10.6 $  _
  • 134. $  npm  adduser Username:  (jayharris)  jayharris Password: Email:  (jay@aranasoft.com)  _
  • 137. {  name:  'morale',    description:  'Async  API  wrapper  for  Morale',    'dist-­‐tags':  {  latest:  '0.2.0'  },    versions:        [  '0.1.0',          '0.1.2',          '0.2.0'  ],    maintainers:  'jayharris  <jay@aranasoft.com>',    time:        {  '0.1.0':  '2012-­‐01-­‐23T03:24:59.824Z',          '0.1.2':  '2012-­‐01-­‐25T23:20:52.927Z',          '0.2.0':  '2012-­‐08-­‐13T16:23:28.488Z'  },    author:  'Arana  Software  <info@aranasoft.com>',    repository:        {  type:  'git',          url:  'git://github.com/aranasoft/morale-­‐node.git'  },    users:  {  fgribreau:  true  },    version:  '0.2.0',
  • 138. $  npm  publish npm  http  PUT  https://registry.npmjs.org/morale npm  http  409  https://registry.npmjs.org/morale npm  http  GET  https://registry.npmjs.org/morale npm  http  200  https://registry.npmjs.org/morale npm  http  PUT  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest npm  http  201  https://registry.npmjs.org/morale/0.2.1/-­‐tag/latest npm  http  GET  https://registry.npmjs.org/morale npm  http  200  https://registry.npmjs.org/morale npm  http  PUT  https://registry.npmjs.org/morale/-­‐/ morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b npm  http  201  https://registry.npmjs.org/morale/-­‐/ morale-­‐0.2.1.tgz/-­‐rev/25-­‐c9bbf49ea0bd2a750e257153fab5794b +  morale@0.2.1 $  _
  • 139. {  name:  'morale',    description:  'Async  API  wrapper  for  Morale',    'dist-­‐tags':  {  latest:  '0.2.1'  },    versions:        [  '0.1.0',          '0.1.2',          '0.2.0',          '0.2.1'  ],    maintainers:  'jayharris  <jay@aranasoft.com>',    time:        {  '0.1.0':  '2012-­‐01-­‐23T03:24:59.824Z',          '0.1.2':  '2012-­‐01-­‐25T23:20:52.927Z',          '0.2.0':  '2012-­‐08-­‐13T16:23:28.488Z',          '0.2.1':  '2012-­‐08-­‐30T19:10:20.133Z'  },    author:  'Arana  Software  <info@aranasoft.com>',    repository:        {  type:  'git',          url:  'git://github.com/aranasoft/morale-­‐node.git'  },
  • 141. ./package.json 1 { "name": "Sample", 2 "version": "0.1.0", 3 "description": "This is a sample module", 4 "main": "index.js", 5 "scripts": { 6 "test": "echo "Error: no tests avail." && exit 1" 7 }, 8 "author": "Jay Harris", 9 "license": "BSD", 10 "private": "true" 11 12 } 13 14 15 16
  • 142. $  npm  publish npm  ERR!  Error:  This  package  has  been  marked  as  private npm  ERR!  Remove  the  'private'  field  from  the  package.json  to   publish  it. $  _
  • 144. $  npm  shrinkwrap wrote  npm-­‐shrinkwrap.json $  _
  • 145. 1 { "name": "morale", 2 "version": "0.2.1", 3 "dependencies": { 4 "underscore": { 5 "version": "1.3.3" 6 }, 7 "mocha": { 8 "version": "1.3.0", 9 "dependencies": { 10 "commander": { 11 "version": "0.6.1" 12 }, 13 "growl": { 14 "version": "1.5.1" 15 }, 16 "jade": { 17 "version": "0.26.3", 18
  • 146. $  rm  npm-­‐shrinkwrap.json $  npm  update $  npm  test $  npm  shrinkwrap
  • 148. Go make some Awesome
  • 149. jay harris P R E S I D E N T jay@aranasoft.com #nodemoduledev @jayharris