简体   繁体   English

在 Node.js 中使用 Jest 进行单元测试

[英]Unit testing With Jest in Node.js

I'm very new to unit testing and very excited about it.我是单元测试的新手,对此非常兴奋。 But I've uncertainty whether I should add defensive programming style or not to my production code.但是我不确定是否应该在我的生产代码中添加防御性编程风格。 So, please see the following codes.所以,请看下面的代码。

calclateFinalYearGPA.js (production code) calclateFinalYearGPA.js(生产代码)

const _ = require('lodash');
const getGPAPoint = require('./getGPAPoint');

module.exports = function (gradings) {
  let totalPoint = 0;

  gradings.forEach((grading) => {
    const grade = grading.grading.grade.name;
    const point = getGPAPoint(grade);
    totalPoint += point;
  });

  const finalYearGPA = _.round(totalPoint / gradings.length, 1);

  return finalYearGPA;
};

The gradings is an array of objects which is pulled from the db, with the following structure. gradings是从数据库中提取的对象数组,具有以下结构。

"gradings": [
    {
        "grading": {
            "gradeId": 3,
            "grade": {
                "gradeId": 3,
                "name": "A-"
            }
        }
    },
    ...
]

In my calculateFinalYearGPA.js , I loop through that array and extract grading.grade.name which is A- in the above structure, and pass it to getGPAPoint .在我的calculateFinalYearGPA.js中,我遍历该数组并提取上面结构中的A-grading.grade.name ,并将其传递给getGPAPoint It will return the decimal number.它将返回十进制数。

So, now in my calculateFinalYearGPA.test.js test, I've add the following code which is test whether it fails when gradings is not an array.所以,现在在我的calculateFinalYearGPA.test.js测试中,我添加了以下代码,用于测试当gradings不是数组时它是否失败。

const calculateFinalYearGPA = require('../../../utils/calculateFinalYearGPA');

describe('calculateFinalYearGPA', () => {
  it('should throw an exception if input is not an array', () => {
    const inputs = [1, 'a', null, undefined, {}];
    inputs.forEach((i) => {
      expect(() => {
        calculateFinalYearGPA(i);
      }).toThrow();
    });
  });
});

So, now I need to add some defensive programming code to my production code.所以,现在我需要在生产代码中添加一些防御性编程代码。

if (gradings.constructor !== Array)
    throw new Error(`Expected to get an array, got ${typeof gradings}.`);

The way I'm doing is correct?我的做法对吗? Should I test the gradings array has the proper structure as well?我是否应该测试gradings数组是否也具有正确的结构? If so, I need to add some code that nothing with business logic is done but check the gradings array's structure.如果是这样,我需要添加一些代码,除了检查gradings数组的结构外,不执行任何业务逻辑。 My production code will populate with that kind of code.我的生产代码将填充这种代码。 Is it supposed to be?它应该是吗?

What is the proper ways to test my calculateFinalYearGPA.js ?测试我的calculateFinalYearGPA.js的正确方法是什么?

Actually I don't think that correct, I mean to expect it will throw an error , throwing error logically means that something unexpected happened其实我不认为那是正确的,我的意思是期望它会抛出一个错误,逻辑上抛出错误意味着发生了意想不到的事情

so the right way to test the structure of the input is within calculateFinalYearGPA.js file, like the following:所以测试输入结构的正确方法是在calculateFinalYearGPA.js文件中,如下所示:

module.exports = function (gradings) {

   if(!Array.isArray(gradings)) {
      throw new Error(`Expected to get an array, got ${typeof gradings}.`);
   }
  let totalPoint = 0;
  ...
};

But in case you need to handle the error in jest or you might check it at least, I just recommend you to create a custom Error class, so you can manipulate as you wish, so:但是如果你需要开玩笑地处理错误或者你至少可以检查它,我只建议你创建一个自定义Error class,这样你就可以随意操作,所以:

class CustomError extends Error {
  constructor(code, message) {
    const fullMsg = message ? `${code}: ${message}` : code;
    super(fullMsg);
    this.name = code;
    this.code = code;
    this.message = fullMsg;
  }
  
  toString() {
    return this.message;
  }
}

Note: excpect(SOME_THING).toThrow() in jest will catch any error, so you have to be sure which error would fail the test and which not.注意:开玩笑的excpect(SOME_THING).toThrow()会捕获任何错误,因此您必须确定哪些错误会导致测试失败,哪些不会。

so now we have inside calculateFinalYearGPA.js file所以现在我们有内部calculateFinalYearGPA.js文件

module.exports = function (gradings) {

   if(!Array.isArray(gradings)) {
      throw new CustomError(799, `Expected to get an array, got ${typeof gradings}.`);
   }
  let totalPoint = 0;
  ...
};

Finally for testing最后进行测试

const calculateFinalYearGPA = require('../../../utils/calculateFinalYearGPA');

describe('calculateFinalYearGPA', () => {
  it('should throw an exception if input is not an array', () => {
    const inputs = [1, 'a', null, undefined, {}];
    inputs.forEach((i) => {
      try {
          calculateFinalYearGPA(i);
        } catch(e) {
         expect(e.code).toBe(799); // 799 is an optional number which refers the type mis-matched 
       }
    });
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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