单元测试就是强制您的代码确保它采用特定路径以及何时采用该路径,以确保事情符合预期。单元测试包括 (1) 强制代码采用特定路径/分支的代码和 (2) 期望 - 例如expect(spy).to.notHaveBeenCalled() 或 expect(a).toStictEqual(1)
您的主要工具是:
存根:在测试套件中调用的方法,而不是它们存根的真实方法。
spies:间谍的作用与存根相同,但更多。间谍不仅允许您返回不同的值。它们还允许您检查方法是否被调用、调用了多少次、调用时传递给该方法的值等等。
这里的想法是您只想测试您正在测试的submitForm 方法中的代码,而不是该方法之外的任何代码。将submitForm 视为您正在测试的单元。
我不打算为您编写代码,因为我没有时间,但这是您想要采用的基本方法。
首先,你要测试所有的代码路径,你一共有4个:
代码路径1:不进入顶层IF语句
在这里,您需要创建一个间谍/存根。您的测试将用 spy / stub 替换真正的 this.login 方法(仅在您的测试套件内 - 无需更改您正在测试的代码)。 this.login 方法的 spy / stub 必须返回 false。在这个测试中,你会期望openMulti 没有被调用,closePop 也没有被调用。您需要监视这两种方法以确保它们未被调用。
代码路径2:进入顶层IF语句,执行嵌套IF语句的IF分支
在这里你需要再次窥探/存根this.login - 这次强制它返回true。您需要将this.inputMulti.nativeElement.checked 的值初始化为真(在您的测试套件中)。并且您会期望 this.openMulti 已被调用。
代码路径3:进入顶层IF语句,执行嵌套IF语句的ELSE IF分支
与 (2) 类似的方法,但在这里您需要确保 this.inputMulti.nativeElement.checked 为假,this.inputSolo 为真。您会期望路由器将调用navigate 方法并调用closePop。您甚至可能想要测试 openMulti 未被调用。
代码路径4:进入顶层IF语句,不执行嵌套IF语句中的任何分支
与以前的方法相同。期望什么都不会被调用。
遗憾的是,单元测试没有简单的方法。你只需要潜入,感受痛苦并习惯它背后的思考以及如何编写代码。后者有很多有用的教程。这个答案更侧重于思考。
如果您使用istanbul(您可能在后台使用它),则启用覆盖。它将创建一个覆盖文件夹。在此覆盖文件夹中,您将找到一个 HTML 文件,您可以右键单击并在浏览器中打开它,其中显示了哪些代码路径/分支已经过测试(哪些没有)。
一切顺利。