在Angular中测试具有多个依赖项的控制器

时间:2014-06-11 11:37:01

标签: angularjs unit-testing jasmine

我正在学习为我的角应用程序编写单元测试。我的控制器有几个依赖资源,工厂,服务等

angular.module('app').controller('Ctrl1',['$scope','Factory1','Factory2','Resource1','Resource2' ... and so on 

当然,Resource1,Resource2等从服务器获取数据。其中一些资源用于从服务器获取数据并初始化$ scope。

在网上阅读了无数的教程后,我对正确编写茉莉花测试的方法提出了一些疑问

  1. 在茉莉花测试的beforeEach部分,我想是立即提供所有依赖项,或者我应该只提供我关心测试的那些

  2. 我想要测试的是,Resource1被调用并获取一些数据并初始化$ scope的某些部分,然后调用Resource2并获取一些数据并初始化其他部分的范围等

  3. 执行上述操作的正确方法是什么。我的意思是我实际上是想在测试中获取数据,或者我应该使用一些模拟http服务。我知道教程提到我们应该使用模拟http服务但是接下来我将如何测试我的控制器,因为我实际上并没有获取正确的数据。

    这部分真的让人感到困惑,我还没有找到一篇明确解释这个问题的博客/文章(我可能只会写一篇,但我确定其他人也很困惑)

1 个答案:

答案 0 :(得分:1)

提供依赖关系的位置

您应该在第一个beforeEach语句中提供所有依赖项。我用SinonJs模拟/假冒我的。这有助于您利用angular的依赖注入来隔离应用程序的每个部分。您永远不应该调用依赖项并期望它的实际实例在单元测试中返回数据,因为这会增加代码的耦合并使其更加脆弱。

模拟资源调用

对于资源调用,我只是创建一个带有promises和whatnot的虚假资源对象。然后,您可以解决或拒绝这些承诺,并提供虚假数据来测试您的控制器逻辑。

在下面的内容中,我基本上嘲笑了整个承诺链。您只需告诉您的测试拒绝或解决这些承诺,伪造成功或失败的资源调用。然后,您必须确保您的范围与scope.$apply()一致。我实际上忘了这样做,这给我带来了很多麻烦。

结论

这是Plunk。如果您需要了解我如何测试我的存储库中的实际资源代码,请告诉我。在那些服务中,我必须实际模拟出HTTP调用,Angular非常容易。

我不确定这是“最佳实践”,但它对我有用。我通过查看其他人的源代码并观看此Pluralsite视频AngularJS Fundamentals来学习基础知识,该视频的测试部分非常小。

有用的资源

  • Testing AngularJS Directives。这是Angular中最难测试和理解的东西。或者至少它适合我。

  • 这个是Dependency Injection in Angular。我有它标记 关于他们开始谈论单元测试的地方。

  • 这个Plural Sight Course让我开始测试JavaScript。如果你是初学者,非常有助于学习Jasmine。

  • 如果你想看看Jasmine测试的实际效果,AngularJS Github repo非常有用。这是一组模拟HTTP后端的tests