原生 Node.js 单元测试笔记

这两周都在写一个和项目相关的计算器,算是试行的一个测试驱动开发的模式,测试代码有写了几千行了,因为对于原生Node.js测试还不是很熟悉,有很多复制粘贴的代码,其中一个就是设计到debug模式。

import assert from "node:assert";
import { test } from "node:test";

export class Calculator {
	debug = false;

	constructor(options, debug = false) {
		this.debug = debug;
		this.options = options;
	}

	getTotal() {
		// Say we want to print out the options when we're in debug mode.
		if (!!this.debug) {
			console.log('options: ', this.options);
		}

		// Do some logic and return the total.
		return 234;
	}
}

test("Calculate", async (t) => {
	await t.test("Test case 1", () => {
		const options = {
			// ... some options.
		};
		const calculator = new Calculator(options, true);
		assert.strictEqual(calculator.getTotal(), 234);
	});

	await t.test("Test case 2", () => {
		const options = {
			// ... some options.
		};
		const calculator = new Calculator(options, true);
		assert.strictEqual(calculator.getTotal(), 234);
	});

	await t.test("Test case 3", () => {
		const options = {
			// ... some options.
		};
		const calculator = new Calculator(options);
		assert.strictEqual(calculator.getTotal(), 234);
	});
});

非常简单的一个例子,假如我们的测试非常多时,每次传入debug=true第二个参数有点繁琐,我想的是可以创建一个factory函数来简化。

import assert from "node:assert";
import { test } from "node:test";

export class Calculator {
	debug = false;

	constructor(options, debug = false) {
		this.debug = debug;
		this.options = options;
	}

	getTotal() {
		// Say we want to print out the options when we're in debug mode.
		if (!!this.debug) {
			console.log('options: ', this.options);
		}

		// Do some logic and return the total.
		return 234;
	}
}

function createCalculatorWithDebug(options) {
	return new Calculator(options, true);
}

test("Calculate", async (t) => {
	await t.test("Test case 1", () => {
		const options = {
			// ... some options.
		};
		const calculator = createCalculatorWithDebug(options);
		assert.strictEqual(calculator.getTotal(), 234);
	});

	await t.test("Test case 2", () => {
		const options = {
			// ... some options.
		};
		const calculator = createCalculatorWithDebug(options);
		assert.strictEqual(calculator.getTotal(), 234);
	});

	await t.test("Test case 3", () => {
		const options = {
			// ... some options.
		};
		const calculator = createCalculatorWithDebug(options);
		assert.strictEqual(calculator.getTotal(), 234);
	});
});
assert.strictEqual(calculator.calculate(selections[0], selections[1], amount, true), 0);

当重构代码时,可能会将得出总数的函数改为calculator.getResult(),那么测试文件中所有的函数都要修改。

assert.strictEqual(calculator.calculate(selections[0], selections[1], amount, true), 0); 
// 改成
assert.strictEqual(calculator.getResult(), 0);

访客留言

《 “原生 Node.js 单元测试笔记” 》 有 7 条评论

  1. 远程前端brandon 的头像

    突然想到本网站可以有的一个需求,就是写完一篇文章后,如果想要分享给之前留言过的伙伴,那么我作为管理员可以增加一个留言,例如:“@some-user, Hi, 我刚刚写了这篇文章,其中提到什么什么,有空可以交流下。”

    那么作为管理员,后台在留言板下面可以增加一个新的控件,比如:“发送邮件给: [输入框]”,添加该用户的邮件,则这个留言提交后会自动发送一封邮件给已添加到表单里面的这个用户。

  2. 远程前端brandon 的头像

    添加了php代码,现在测试是否可以发送邮件给指定用户。

  3. […] 我在这篇博客留言提醒自己增加这个需求:https://heybran.tech/node-js-testing-notes/#comment-54,在此记录一下实现的代码。查看了WordPress关于留言表单的源码:https://github.com/WordPress/wordpress-develop/blob/6.6.2/src/wp-includes/comment-template.php#L2784,我可以在comment_form_field_comment这个filter上面添加一个回调函数。 […]

  4. jinmokai 的头像

    最近做一个工具库,打算用作自己常用工具库,开始本想写原生node的单元测试,不过发现不支持typescript,为了方便安装了vitest,目前开发体验良好,欢迎pr,提出一些建议。
    https://github.com/JinMokai/js-fn-utils
    已经发布到npmjs上面
    https://www.npmjs.com/package/@jinmokai/utils

  5. 远程前端brandon 的头像

    了解过jsr.io吗?可以直接发布TS文件,不用打包。

  6. jinmokai 的头像

    听过这个 没有深入了解 不过没有用过😅
    看来 我要补充一下这个地方了

  7. 远程前端brandon 的头像

    突然想到,等你后面域名更改后,你在我这网站留言使用的网站已经存入数据库,我需要写一个脚本来更新下数据库的内容。记录下算是提醒自己吧。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注