简体   繁体   中英

Testing ejs/nodejs function that uses mongoDB with mocha/chai

mongo is set up like this in homeController.js

const MongoDB = require("mongodb").MongoClient,
  dbURL = "mongodb://localhost:27017",
  dbName = "usersdb";
const collectionName = "contacts";
var test = require('assert');
var col;

var usersArray = []; // define an empty array as a placeholder
var gradesArray = [];

MongoDB.connect(dbURL, {
    useUnifiedTopology: true,
    useNewUrlParser: true,
    useCreateIndex: true
  },
  (error, client) => {
    if (error) throw error;
    let db = client.db(dbName);
    col = db.collection(collectionName, {
      safe: false,
      useUnifiedTechnology: true
    }, (err, r) => {
      if (err) {
        console.log("Something is wrong in db.collection");
      }
    });

    col.find()
      .toArray((error, userData) => {
        if (error) throw error;
        usersArray = userData; // store all users in the array users[]
        //console.log(userData);
      });
    //  console.log(`All users: ${usersArray}`);
  });

I have a function in homeController.js that I want to test, it take a name and array of grades, converts the grades, checks if they're valid, and pushes them to the database. The function looks like this and uses the col variable:

router.addUsers = (req, res) => {
  console.log("in homeController addUser");

  var newUserName = req.body.name;
  var newUsergrade = req.body.grade;

  var temp = 0;
  newUsergrade.forEach(letter => {
    letter = letter.toUpperCase();
    switch (letter) {
      case 'A':
        letter = 4.0
        break
      case 'A-':
        letter = 3.7
        break
      case 'B+':
        letter = 3.3
        break
      case 'B':
        letter = 3.0
        break
      case 'B-':
        letter = 2.7
        break
      case 'C+':
        letter = 2.3
        break
      case 'C':
        letter = 2.0
        break
      case 'C-':
        letter = 1.7
        break
      case 'D+':
        letter = 1.3
        break
      case 'D':
        letter = 1.0
        break
      case 'F':
        letter = 0.0
        break
    }
    temp += letter;
  });
 var valid = false;
  if (temp / 4 >= 2.5) {
    valid = true;
  } else {
    vaild = false;
  }
  col.insertOne({
    name: newUserName,
    grade: newUsergrade,
    isValid: valid
  }, function(err, r) {
    test.equal(null, err);
    test.equal(1, r.insertedCount);
    col.find({}).toArray((err, userData) => {
      console.log("record found: ", userData);
      usersArray = userData;
    });

  });

Finally, my router.test.js looks like this:

describe("addUsers", () => {
  it("should make sure a user can be added to the array", () => {
    const fakeReq = {
        body: {
          name: 'something',
          grade: ["a", "b", "a", "a"]
        }
      },
      fakeRes = {
        render: () => {}
      };


    router.addUsers(fakeReq, fakeRes);


    //  console.log(router.addUsers(fakeReq, fakeRes))

    expect(usersArray).to.deep.include({
      name: 'something'
    });
  });
});

I am getting an error saying it cant insertOne of undefined, meaning I need the mongoDB part in my test. How can I incorporate this into my test to test if this function adds one entry?

You are testing a middleware as if it were a standalone function. In this case, you should test the route endpoint. For example:

const request = require("supertest");
const expect = require("chai").expect;
const app = require('../app');
const mongoose = require('mongoose');
const faker = require("faker"); // to generate fake data
const Entity = require('../entities/discount'); // import schema
require('dotenv').config();


describe("GET /Entity/{entityID}", () => {
    let body 

    beforeEach(async () => {
        await Entity.deleteMany()

        body = {
            name: faker.name.title(),
            image: faker.image.imageUrl()
        }

        const entity = new Entity({
            _id: new mongoose.Types.ObjectId(),
            ...body
        })

        await entity.save()

    })

    describe("case of success", () => {
        it("should work and return status 200 and message ...", async () => {
            const res = await request(app)
                .get("/entity /" + entityID )

            expect(res.status).to.equal(200);
            expect(res.body).to.exist

            expect(res.body._id).to.exist
            expect(res.body).to.have.property("name", body.name);
            expect(res.body).to.have.property("image", body.image);

        })
    })

})

But if you want to test each specific function, you should generate functions that deal with a certain action and test these actions in particular.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM