npm install to bring it in.
$ npm install --save mongoose
$ grep mongoose package.json
"mongoose": "~4.0.1"
Now we’ll create an initial test to just test mongoose out.
~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ cat test/post-test.coffee
mongoose = require 'mongoose'
Post = require '../models/Post'
chai = require 'chai'
expect = chai.expect
describe 'Post', ->
before (done) ->
mongoose.connect 'mongodb://localhost/coffeepress', ->
Post.remove done
it 'should create a new post', (done) ->
post = new Post(title:'First!', body:'First post!')
post.save ->
Post.findOne _id: post._id, (err, retrievedPost) ->
expect(retrievedPost.title).eql "First!"
expect(retrievedPost.body).eql "First post!"
done()
mongoose and the model object that we’re going
to create
before hook (which runs once before anything else in the test runs)
to both connect to the database and then remove all of the Post objects
from mongodb
beforeEach() hook contains code that runs before every test in a describe block.
afterEach() hook contains code that runs after every test in a describe block.
before() hook contains code that runs before any tests in each describe() block run. It runs before the first run of a beforeEach() hook.
after() hook contains code that runs after all tests in each describe() block have run. The after() hook will run after the last afterEach() hook.
Post.remove({ title: 'first' }, function (err) {
if (err) return handleError(err);
// removed!
});
When no condition is specified all the documents are removed
done callback to the remove call
so that tests
don’t run until all Posts have been removed
Post instance.
You can pass an object literal in to set properties on the model, so we do that here
post = new Post(title:'First!', body:'First post!')
save callback we look the post back up and verify certain attributes have been set
post.save ->
Post.findOne _id: post._id, (err, retrievedPost) ->
expect(retrievedPost.title).eql "First!"
expect(retrievedPost.body).eql "First post!"
done()
find, findById, findOne, or where
static methods.
{_id: post._id} es la condición y especifica el documento que
queremos buscar
(err, retrievedPost) -> ... es la callback que se ejecuta
cuando el documento ha sido encontrado.
Aprovechamos esta callback para hacer
las pruebas y llamar finalmente a done() para indicar la finalización de las pruebas.
~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp test
[11:05:16] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js
[11:05:16] Starting 'mocha'...
module.js:340
throw err;
^
Error: Cannot find module '../models/Post'
Now let’s implement our model:
$ mkdir models $ cat models/Post.coffee mongoose = require 'mongoose' Post = new mongoose.Schema( title: String body: String ) module.exports = mongoose.model 'Post', Post
Post = new mongoose.Schema( title: String body: String )Each schema maps to a MongoDB collection and defines the shape of the documents within that collection.
Post Schema
into a Model we can work with. To do so, we pass it into
mongoose.model(modelName, schema):
mongoose.model 'Post', Post
mongod no está arrancado:
$ gulp test
[11:34:22] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js
[11:34:22] Starting 'mocha'...
Post
1) "before all" hook
routes
index
ok: should display index with posts
new post
ok: should display the add post page
2 passing (2s)
1 failing
1) Post "before all" hook:
Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.
Será mejor extender el gulpfile
un poco para controlar el estado del servidor
mongod antes y después de las
pruebas:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ cat gulpfile.coffee
gulp = require('gulp')
shell = require('gulp-shell')
fs = require('fs')
# run coffee server via nodemon https://github.com/remy/nodemon
gulp.task 'default', ->
gulp.src('').pipe shell( 'DEBUG=coffeepress:* nodemon bin/www.coffee' )
gulp.task 'test', [ 'mocha' ]
# run mocha
gulp.task 'mocha', ->
gulp.src('')
.pipe shell "mocha --compilers coffee:coffee-script/register --invert --grep 'feature' -R spec"
# run mongod server
gulp.task 'mongod', ->
gulp.src('')
.pipe shell([ 'mongod --config mongod.conf 2>1 > /usr/local/var/mongodb/salida &' ])
# kill mongod server
gulp.task 'killmongo', ->
fs.readFile '/usr/local/var/mongodb/mongo.pid', 'utf8', (err, pid) ->
return console.log(err) if (err)
console.log("killing #{pid}")
gulp.src('').pipe shell("kill #{pid}")
# show mongod PID
gulp.task 'ps', ->
gulp.src('')
.pipe shell( 'ps -fA | grep mongod')
Este es el fichero de configuración para mongod que estoy usando:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ cat mongod.conf # Store data in /usr/local/var/mongodb instead of the default /data/db dbpath = /usr/local/var/mongodb # Append logs to /usr/local/var/mongo.log logpath = /usr/local/var/mongodb/mongo.log logappend = true # Save the PID of the daemon on that file pidfilepath = /usr/local/var/mongodb/mongo.pid # Only accept local connections bind_ip = 127.0.0.1
Ahora podemos fácilmente comprobar si el servidor mongo está activo:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp ps [14:23:52] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js [14:23:52] Starting 'ps'... 501 33200 33199 0 2:23PM ttys011 0:00.01 /bin/sh -c ps -fA | grep mongod 501 33202 33200 0 2:23PM ttys011 0:00.00 grep mongod [14:23:53] Finished 'ps' after 107 msVemos que no. Lo arrancamos:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp mongod [14:23:59] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js [14:23:59] Starting 'mongod'... [14:24:00] Finished 'mongod' after 37 msComprobamos que efectivamente está corriendo:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp ps [14:24:11] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js [14:24:11] Starting 'ps'... 501 33212 1 0 2:24PM ttys011 0:00.25 mongod --config mongod.conf 501 33228 33227 0 2:24PM ttys011 0:00.00 /bin/sh -c ps -fA | grep mongod 501 33230 33228 0 2:24PM ttys011 0:00.00 grep mongod [14:24:11] Finished 'ps' after 82 msEjecutamos las pruebas:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp test
[14:24:21] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js
[14:24:21] Starting 'mocha'...
Post
ok: should create a new post
routes
index
ok: should display index with posts
new post
ok: should display the add post page
3 passing (179ms)
[14:24:22] Finished 'mocha' after 1.4 s
[14:24:22] Starting 'test'...
[14:24:22] Finished 'test' after 17 microseg
Vemos que la prueba should create a new post pasa.
Si lo deseamos podemos parar el servidor mongod:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp killmongo [14:24:42] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js [14:24:42] Starting 'killmongo'... [14:24:42] Finished 'killmongo' after 537 microseg killing 33212Comprobamos que - efectivamente - el proceso no existe:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp ps [14:24:45] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js [14:24:45] Starting 'ps'... 501 33274 33270 0 2:24PM ttys011 0:00.00 /bin/sh -c ps -fA | grep mongod 501 33276 33274 0 2:24PM ttys011 0:00.00 grep mongod [14:24:46] Finished 'ps' after 89 ms
Now let’s refit our routes to use the Post
model instead of an in memory array.
En el fichero app.coffee cargamos la librería mongoose y conectamos
con la base de datos:
...
bodyParser = require('body-parser')
mongoose = require "mongoose"
mongoose.connect 'mongodb://localhost/coffeepress'
routes = require('./routes/index')
...
Los mayores cambios los hacemos en las rutas:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ cat routes/index.coffee
express = require('express')
Post = require '../models/Post'
debug = require('debug')('coffeepress:server')
util = require 'util'
module.exports =
index: (req, res) ->
Post.find {}, (err, posts) ->
res.render "index",
title: "My Blog"
posts: posts
newPost: (req, res) ->
res.render('add_post', {title: "Write New Post"})
addPost: (req, res) ->
post = req.body
new Post(post).save ->
res.redirect '/'
viewPost: (req, res) ->
Post.findById req.params.id, (err, post) ->
res.render 'post', post: post, title: post.title
Acabaremos mejorando un poco las pruebas:
[~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ cat test/routes-test.coffee
chai = require 'chai'
expect = chai.expect
mongoose = require "mongoose"
Post = require "../models/Post"
routes = require '../routes/index'
describe 'routes', ->
req =
params: {}
body: {}
res =
redirect: (route) ->
# do nothing
render: (view, vars) ->
# do nothing
before (done) ->
mongoose.connect 'mongodb://localhost/coffeepress', ->
Post.remove done
describe 'index', ->
it "should display index with posts", (done) ->
res.render = (view, vars) -> # redefinimos render
expect(view).to.be.equal 'index'
expect(vars.title).to.be.equal 'My Blog'
expect(vars.posts).deep.equal []
done()
routes.index(req, res)
describe 'new post', ->
it "should display the add post page", (done)->
res.render = (view, vars) -> # redefinimos render
expect(view).to.be.equal 'add_post'
expect(vars.title).to.be.equal 'Write New Post'
done()
routes.newPost(req, res)
it "should add a new post when posted to", (done) ->
req.body =
title: "My Post!"
body: "My wonderful post."
routes.addPost req, redirect: (route) ->
expect(route).eql "/"
routes.index req, render: (view, vars) ->
expect(view).equal "index"
expect(vars.posts[0].title).eql 'My Post!'
expect(vars.posts[0].body).eql "My wonderful post."
done()
Cuando las ejecutamos tenemos:
~/javascript/expressjs/clase-express-coffee(preparapl20042015)]$ gulp test
[22:14:06] Using gulpfile ~/local/src/javascript/expressjs/clase-express-coffee/gulpfile.js
[22:14:06] Starting 'mocha'...
Post
ok: should create a new post
routes
index
ok: should display index with posts
new post
ok: should display the add post page
ok: should add a new post when posted to
4 passing (165ms)
[22:14:07] Finished 'mocha' after 1.42 s
[22:14:07] Starting 'test'...
[22:14:07] Finished 'test' after 17 micros
Casiano Rodríguez León