如何对$scope进行单元测试?广播、美元范围.$on使用Jasmine



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

所以简而言之,我有两个控制器,第一个控制器$broadcast和'Id',第二个控制器用$on获取该Id,然后将该Id传递给中间的service,这使得$http ajax调用并返回单个Book对象。

我如何单元测试$scope。广播、美元范围。$on using Jasmine

firstCtrl

.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服务,请告诉我。

预期行为

所以从我的头脑中,理想情况下,我想测试每一个可能的场景,但像下面这样的,然后可以使用:

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

谢谢大家!

首先你应该在$rootScope上做广播,然后你可以在$scope上接收。现在进行测试。我假设您想通过bookService$http包含对API的实际请求。这可以被嘲笑,但我将专注于真正的电话。如果你需要模拟的,请告诉我。

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

  • 初始化你的应用
  • 注入$controller$rootScope$httpBackendbookService
  • 为firstController和SecondController创建作用域,并将其存储在变量
  • bookService$httpBackend存储在变量
  • 实例化控制器并存储它们

然后在实际的测试中,您必须告诉$httpBackend当它缓存图书(或图书)的请求时该做什么。构造$httpBackend.whenGET("/api/books/1").passThrough();将url为"/api/books/1"的请求传递给服务器。接下来,您必须在firstScope上设置属性selectedRows,以便它满足firstCtrlselectGridRow函数中的条件。

现在你可以调用selectGridRow函数来触发广播和API调用。但是您必须将它包装在runs函数中,以便Jasmine将其识别为异步调用并等待它完成。在waitsFor调用中定义了"等待"。它将等待,直到它得到一个书,它等待最多5000毫秒,然后测试将被标记为失败。

最后一步是检查预期结果。我们不需要再检查undefined,因为无论如何测试都不会到达这里。检查必须再次包装runs调用,以便在'waitsFor'成功后执行。

下面是完整的代码:

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);
        });
    });
});

最新更新