使用AngularJS进行Jasmine测试,Object [object Object]没有方法适用

时间:2013-08-21 08:19:17

标签: javascript unit-testing testing angularjs jasmine

在我的新项目中,我一直在使用AngularJS和Jasmine。我对Jasmine有相当丰富的经验,但之前没有将它与AngularJS结合使用。我正在尝试编写一个非常非常简单的单元测试,但我无法使其正常工作。我只是根据文档做了一个非常简单的测试:

describe("Controller tests", function () {

    describe("LoginController", function () {

        var scope = {};

        beforeEach(inject(function ($rootScope, $controller) {
            scope = $rootScope.$new();
            $controller(LoginController, {
                $scope: scope
            });
        }));

        it("should prepare the login page", function () {
            scope.prepareLoginPage();
        });

    });

});

但是,它根本不起作用。 LoginController是一个非常基本的功能,根本没什么特别之处。当我尝试使用Jasmine HTML runner时,我得到以下输出:

TypeError: Object [object Object] has no method 'apply'
TypeError: Object [object Object] has no method 'apply'
    at jasmine.Block.execute (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:1064:23)
    at jasmine.Queue.next_ (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2096:37)
    at jasmine.Queue.start (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2049:10)
    at jasmine.Spec.execute (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2376:16)
    at jasmine.Queue.next_ (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2096:37)
    at jasmine.Queue.start (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2049:10)
    at jasmine.Suite.execute (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2521:16)
    at jasmine.Queue.next_ (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2096:37)
    at jasmine.Queue.start (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2049:10)
    at jasmine.Suite.execute (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2521:16)
TypeError: Cannot call method 'prepareLoginPage' of undefined
TypeError: Cannot call method 'prepareLoginPage' of undefined
    at null.<anonymous> (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/angularjs/seabirds/controllersTest.js:18:29)
    at jasmine.Block.execute (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:1064:23)
    at jasmine.Queue.next_ (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2096:37)
    at jasmine.Queue.start (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2049:10)
    at jasmine.Spec.execute (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2376:16)
    at jasmine.Queue.next_ (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2096:37)
    at jasmine.Queue.start (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2049:10)
    at jasmine.Suite.execute (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2521:16)
    at jasmine.Queue.next_ (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2096:37)
    at jasmine.Queue.start (file:///Users/geroen_joris/Development/Source/LifeWatchINBO/SeaBirds/src/test/javascript/lib/jasmine-1.3.1/jasmine.js:2049:10)

问题似乎在于beforeEach(),因为它接受的唯一语法是:

beforeEach(function(){...});

但即使我引入了这个(与AngularJS documentation相矛盾),控制器和范围仍未初始化。有人有指点吗?

我正在使用Jasmine 1.3.1和AngularJS 1.0.7。

2 个答案:

答案 0 :(得分:2)

显然,茉莉花的规格范围中没有定义LoginController。 您应该在应用程序模块中定义控制器:

angular.module("myApp, []).controller("LoginController", function($scope) {});

..并使用$controller("LoginController", {})在规范中实例化它。

答案 1 :(得分:0)

好的,我弄清楚出了什么问题。我假设您可以像任何其他Jasmine测试一样运行测试,这意味着:使用SpecRunner.html文件。

然而,这不是真的。您只能使用Karma运行AngularJS测试。虽然这看似合乎逻辑,但说实话,我觉得这是不合逻辑的。 最重要的一点是你甚至看到你正在加载一个JASMINE_ADAPTER(在你的karma配置文件中),它基本上覆盖了Jasmine测试框架的一部分。说实话,我发现这是一个非常糟糕的解决方案,并且与AngularJS团队的预期不同。如果你开始以他们的方式覆盖框架的内部,那么你正在攻击解决方案,这是从长远来看,你不想走下去。

我已经写了一段时间的JS测试,并发现Jasmine非常轻巧,易于实现。我之前的一个项目,我们使用了KnockoutJS。我当时实现了Jasmine,能够为JS做TDD。它很简单,而且工作得很好。 因此,对于这项任务,我选择使用AngularJS作为一种技术,因为我对它的工作方式非常考虑,在摆弄了一点之后。我承认,我没有尝试编写单元测试,因为它们都是以Jasmine为基础的,而且它似乎是一个明智的选择。在我看来,重要的经验教训。

现在,我需要安装Node.JS,Karma和PhantomJS才能在我们的构建服务器上运行这些测试。

在我的书中,AngularJS失去了很多分。我甚至怀疑整个测试设置的投资是否值得选择框架。我承认,AngularJS在许多层面上都优于其竞争对手 - 但没有什么,实际上什么也没有,能够编写完全测试的软件,最好是TDD风格。哦,是的,Karma似乎是炸弹,所有自动检查目录和所有 - 但想一想:你需要拖入所有的依赖(这不是微不足道),以便能够使用它。 Pure Jasmine开箱即用,采用Maven版本无头,配置极少。

哼。无感。