Creating the product model

In the previous chapter, we learned all that we need to know about Mongoose, MongoDB, and Schemas. We are going to use that knowledge widely to build our Product schema and test it.

We do not want to leave the test till the very end, because sometimes, we tend to skip things that are left for the end. With the test-first approach, our tests will serve as guidelines for things to be implemented. We are going to use Mocha, which is very modular and supports multiple assertion libraries. For testing the models, we are going to use a BDD style assertion should.js (also developed for TJ). You can study all the possible assertions at https://github.com/tj/should.js.

Testing the products model

Now, create the product.model.spec.js file using the following command:

touch server/api/product/product.model.spec.js

Following TDD, we should perform the following steps:

  1. Create a single test, and watch it fail by running grunt test:server.
  2. Implement the code and run grunt test:server again; it should pass this time.
  3. Refactor the tests and code if possible, and the test should still succeed.
  4. Write another test, and repeat this cycle until all tests are completed.

However, it will be very extensive for this book to go on developing and testing one by one. So, we are going to copy the full product.model.spec.js file from https://raw.githubusercontent.com/amejiarosario/meanshop/ch4/server/api/product/product.model.spec.js and paste it.

Let's stop here, and explain what's going on. The first thing that you will notice on opening product.model.spec.js is that we include ProductSchema, which is a generic schema created by the yo generator. We will modify the model later to make all the tests pass.

Most of the BDD style tests are grouped in the describe blocks, and inside these blocks there are it blocks. They are both JavaScript functions that take two parameters: one is the plain English text string, and the other one is a callback function. The it blocks are the ones that define the tests in their callback functions. Notice that some of the callback functions have the done parameter. The done() function helps us to test asynchronous functions, and when called, it also returns errors with done(err). The beforeEach blocks are executed before each it block inside their current describe block. In our case, we are going to remove all the products before starting each test using Product.remove(done). The block beforeEach helps us to test each block in isolation so that the products created in the previous tests do not interfere with the tests that follow.

Run grunt test:server in the console, and watch how all the tests fail. Here's a challenge: Can you make modifications to product.model.js to make all of them pass without seeing the solution?

Product model implementation

The following changes are needed to meet our (test) requirements:

/* server/api/product/product.model.js *excerpt */

var ProductSchema = new Schema({
  title: { type: String, required: true, trim: true },
  price: { type: Number, required: true, min: 0 },
  stock: { type: Number, default: 1 },
  description: String
});

Now all the tests should succeed and will look similar to this:

Product
  ✓ should not create without title 
  ✓ should remove trailing spaces from title 
  ✓ should default stock to 1 
  ✓ should not create without price 
  ✓ should not allow negative price 
  ✓ should save a description

The tests have now documented our Product schema describing what our products do and what it validates.

Running grunt test:server, made the Products tests succeed but it broke the product.integration.js tests. Let's implement the API and fix that.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.255.187