Search code examples
expressmocha.jssupertest

Mocha, testing a put request to an array


I am trying to update my array:

let myDB = [{ post: "post_1", comment: "comment_1" }];

with a put request

app.put("/updatePost", function(req, res) {
  let index = Number(req.body.updateI) - 1;

  let updatedComment = { post: req.body.updateP, comment: req.body.updateC };
  myDB.splice(index, 1, updatedComment);

  res.render("index.ejs", { posts: myDB });

});

It works fine when run manually, but the Mocha/SuperTest test fails:

describe("Put /", function() {
  it("I should access the Put route ", function(done) {
    supertest(myApp.app)
      .put("/updatePost")
      .send({
        updateI: "1",
        updateP: "update_post_1",
        updateC: "update_comment_1"
      })
      .expect(res => {
        if (myApp.myDB[0].updateP !== "update_post_1") {
          throw new Error("Update error" );
        }
     })
      .expect(200)
      .end(function(err, res) {
        if (err) return done(err);
        done();
      });
  });
});

Specifically, the myApp.myDB[0].updateP in the Mocha/SuperTest test returns undefined instead of a string. Any Ideas?


Solution

  • You should change:

    if (myApp.myDB[0].updateP !== "update_post_1") {
      throw new Error("Update error");
    }
    

    to:

    if (myApp.myDB[0].post !== "update_post_1") {
      throw new Error("Update error");
    }
    

    E.g.

    app.js:

    const express = require("express");
    const bodyParser = require("body-parser");
    const app = express();
    
    const myDB = [{ post: "post_1", comment: "comment_1" }];
    
    app.use(bodyParser.json());
    app.put("/updatePost", (req, res) => {
      let index = Number(req.body.updateI) - 1;
    
      let updatedComment = { post: req.body.updateP, comment: req.body.updateC };
      myDB.splice(index, 1, updatedComment);
    
      res.json({ posts: myDB });
    });
    
    module.exports = {
      app,
      myDB,
    };
    

    app.test.js:

    const myApp = require("./app");
    const supertest = require("supertest");
    
    describe("Put /", function() {
      it("I should access the Put route ", function(done) {
        supertest(myApp.app)
          .put("/updatePost")
          .send({
            updateI: "1",
            updateP: "update_post_1",
            updateC: "update_comment_1",
          })
          .expect((res) => {
            console.log(myApp.myDB);
            if (myApp.myDB[0].post !== "update_post_1") {
              throw new Error("Update error");
            }
          })
          .expect(200)
          .end(function(err, res) {
            if (err) return done(err);
            done();
          });
      });
    });
    

    Integration test result with coverage report:

      Put /
    [ { post: 'update_post_1', comment: 'update_comment_1' } ]
        ✓ I should access the Put route  (44ms)
    
    
      1 passing (51ms)
    
    -------------|----------|----------|----------|----------|-------------------|
    File         |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    -------------|----------|----------|----------|----------|-------------------|
    All files    |    90.91 |       50 |      100 |    95.24 |                   |
     app.js      |      100 |      100 |      100 |      100 |                   |
     app.test.js |    81.82 |       50 |      100 |       90 |                16 |
    -------------|----------|----------|----------|----------|-------------------|
    

    As you can see in the output, the value of myDB is

    [ { post: 'update_post_1', comment: 'update_comment_1' } ]

    myApp.myDB[0] will give you

    { post: 'update_post_1', comment: 'update_comment_1' }

    There is no updateP field in this object. That's why myApp.myDB[0].updateP is undefined.

    Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/58709498