我如何单元测试$ scope.broadcast,$范围。$使用茉莉花 [英] How do I unit test $scope.broadcast, $scope.$on using Jasmine

查看:245
本文介绍了我如何单元测试$ scope.broadcast,$范围。$使用茉莉花的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新手,AngularJs /世界的NodeJS,所以原谅,如果这是一个基本的问题,一些。

I'm newbie to AngularJs/NodeJs world, so forgive if this is a basic question to some.

所以,总之我有两个控制器,第一控制器 $广播的'ID',第二控制器读取的编号与 $在,然后通过该ID来一个中间服务,这使得一个 $ HTTP AJAX调用并返回一个图书对象。

So in a nutshell I've two controllers, the first controller $broadcast an 'Id' and the second controller fetches that Id with $on and then passes that Id to an intermediate service, which makes an $http ajax call and returns a single Book object.

如何使用茉莉花我做单元测试$ scope.broadcast,$范围。$

How do I unit test $scope.broadcast, $scope.$on using Jasmine

.controller('firstCtrl', function($scope, ...){
    $scope.selectGridRow = function() {
        if($scope.selectedRows[0].total !=0)
            $scope.$broadcast('id', $scope.selectedRows[0].id);//Just single plain ID
    };
});

secondCtrl

.controller('secondCtrl',
    function($scope, bookService) {
        $scope.$on('id', function(event, id) {
            bookService.getBookDetail(id).then(function(d) {
                $scope.book = d.book;
            });
        });
    });

预期的Json OBJ

var arr = "book" : [ {
            "id" : "1",
            "name" : "Tomcat",
            "edition" : "9.1"
           }
          ]

让我知道,如果有人要我张贴的使用由第二控制器 $ HTTP 服务。

所以从我的头顶,理想情况下,我想测试各种可能的情况,但类似下面,这样就可以消耗:

So from the top of my head, ideally, I would like to test every possible scenario, but something like below, which can then expend:

expect(scope.book).toEqual(arr);
expect(scope.book).not.toEqual(undefined);

谢谢大家!

推荐答案

首先,你应该做 $ rootScope 广播,那么你可以接收 $范围
现在到了测试。我假设你想包括通过 bookService的 $ HTTP 来您的API真正的要求。这可以被嘲笑,但我会专注于实际通话。让我知道如果你需要的嘲笑之一。

First you should do the broadcast on $rootScope then you can receive on $scope. Now to the testing. I assume you want to include real request to your API via bookService and $http. This can be mocked but I'll focus on the real call. Let me know if you need the mocked one.

在实际测试之前,您需要做一些注射/实例:

Before the actual test, you will need to do some injections/instantiations:


  • 初始化你的应用程序

  • 注入 $控制器 $ rootScope $ httpBackend bookService的

  • 创建为firstController和SecondController范围并将其存储在一个变量

  • 存储 bookService的 $ httpBackend 变量

  • 实例化控制器,并将它们存储

  • Initialize your app
  • Inject $controller, $rootScope, $httpBackend and bookService
  • Create scopes for firstController and SecondController and store it in a variable
  • Store bookService and $httpBackend in variables
  • Instantiate the controllers and store them

然后在实际测试中,你必须告诉 $ httpBackend 时,它会缓存书(或电子书)的要求做什么。构建 $ httpBackend.whenGET(/ API /书籍/ 1)直通(); 将通过与URL请求/ API /书籍/ 1到服务器。
接下来你必须设置属性 selectedRows firstScope 所以它满足函数的条件 selectGridRow firstCtrl

Then in the actual test you must tell $httpBackend what to do when it caches request for the books (or books). Construct $httpBackend.whenGET("/api/books/1").passThrough(); will pass request with url "/api/books/1" to the server. Next your must setup property selectedRows on firstScope so it fulfills the condition in function selectGridRow in your firstCtrl.

现在,你可以调用函数 selectGridRow 来触发广播和API调用。但是,你必须在运行功能,使茉莉花认识到这是一个异步调用,并会等待它完成包裹。在等待在 waitsFor 调用所定义。它会等待,直到它得到一本书,它会等待最多5000毫秒然后根据试验失败将被标记。

Now you can call function selectGridRow to trigger the broadcast and API call. But you must wrap it in runs function so Jasmine recognizes this as an async call and will wait for it to finish. The 'waiting' is defined in waitsFor call. It will wait until it gets a book and it waits max 5000 ms then the test will be marked as failed.

最后一步是检查预期的结果。我们没有检查未定义了,因为测试不会得到到这里反正。支票必须重新包装所以它执行afters运行呼叫成功waitsFor。

Last step is to check expected result. We don't have to check for undefined anymore as the test would not get to here anyway. The check must be wrapped again runs call so it is executed afters successful 'waitsFor'.

下面是完整的code:

Here is the full code:

describe("Broadcast between controllers", function () {

    beforeEach(module('app')); //app initialization

    var firstScope;
    var secondScope;

    var bookService;
    var $httpBackend;

    var firstController;
    var secondController;

    beforeEach(inject(function ($controller, $rootScope, _bookService_, _$httpBackend_) {
        firstScope = $rootScope.$new();
        secondScope = $rootScope.$new();

        bookService = _bookService_;
        $httpBackend = _$httpBackend_;

        firstController = $controller('firstCtrl', { $scope: firstScope });
        secondController = $controller('secondCtrl', { $scope: firstScope, bookService: bookService });
    }));


    it("should work", function () {

        $httpBackend.whenGET("/api/books/1").passThrough();

        firstScope.selectedRows = [{ id: 1, total: 1000 }];
        secondScope.book = null;

        runs(function () {
            firstScope.selectGridRow();
        });

        waitsFor(function () {
            return secondScope.book != null;
        }, "Data not received in expected time", 5000);

        runs(function () {
            expect(secondScope.book[0].id).toEqual(1);
        });
    });

});

这篇关于我如何单元测试$ scope.broadcast,$范围。$使用茉莉花的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆