我已经开始使用Mocha + Chai + Sinon库在Node.js(使用TypeScript)中为后端编写单元测试
作为使函数为任何给定输入返回正确输出的一部分,
例如,在登录方法中它是有道理的:
login(userName: string, password: string) : LoginResult
我认为必须验证给定的用户名和密码是字符串而不是未定义。
当给定输入不是字符串时,TypeScript引擎将发出警报,但它不会警告给定输入是未定义的,这是该单元的无效输入(测试方法)。
因此,在代码的开头我使用断言:
assert(userName !== undefined, 'Given "userName" is "undefined");
assert(password !== undefined, 'Given "password" is "undefined");
我想知道这是否是正确的approuch在生产代码中使用断言进行TDD /防御性编程输入验证并验证来自其他方法的响应,或者它可以以某种方式进行改进。
我正在使用assert-plus
库,它可以根据环境变量禁用生产中的断言,这是一个加号,但我不确定是否应该,因为断言允许提供更多指示性错误并避免运行代码在意外的情况下。
谢谢!
答案 0 :(得分:1)
输入验证确实很重要,但这取决于代码在软件中的位置,最后取决于判断。 有两种思考方式,您通常会看到这两种观点不同意分配。
这假定您的代码将脱离上下文,因此您需要在使用该函数之前验证该函数中的无效用户输入。这通常以有据可查的漏洞进行备份。在这种情况下,您要转换每个可断言的情况,并按@Estus Flask的注释将其转换为if&throw。这样做的明显缺点是,您可能会花费大量时间反复验证同一数据。
如果您坚持这种生理习惯,请勿在生产代码中使用断言,请将每个断言转换为if语句,并使用合理的可读错误消息抛出异常。
这假定您已经定义了正确的客户端代码,并且不能将无效数据传递到关键部分。尽管您仍然会尽一切努力来防止远程代码执行,但是由于客户端代码的行为不正确,因此访问未定义值的成员并“崩溃”是可以接受的行为。该错误位于客户端代码中,不应仅将无效数据传递给该函数。然后,输入验证全部在应用程序/库的最外层进行。 (例如在REST路由处理程序中),但以断言的形式在代码中记录有关数据的断言仍然有意义。这些断言可能出于性能原因而应停产,但在暂存和测试代码中可以接受。 (您可以在蓝色/绿色部署过程中将它们保持打开状态,以检查新代码是否起作用。)
如果您遵循这种生理,在生产代码中使用断言来记录代码对输入数据和世界状况所做的断言。这些断言在大多数情况下应该是无效的。