How I unit test $ scope.broadcast, $ scope. $ When using Jasmine

I'm new to the AngularJs / NodeJs world, so goodbye if this is a basic question for some.

So, in a nutshell, I have two controllers, the first controller is $broadcast

"Id" and the second controller retrieves this id using $on

and then passes that id to an intermediate service

, which $http

ajax does and returns one object Book

.

How I unit test $ scope.broadcast, $ scope. $ when 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;
            });
        });
    });

      

expected Json obj

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

      

Let me know if anyone wants me to publish the service $http

used by the second controller.

expected behavior

So, from the very beginning of my head, ideally, I would like to test all possible scenarios, but something like below that can then waste:

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

      

Thanks everyone!

+1


source to share


1 answer


You must first broadcast to $rootScope

, after which you can get it to $scope

. Now for testing. I am assuming you want to include the real request in your API via bookService

and $http

. It might be scoffing, but I'll focus on the real challenge. Let me know if you need a taunt.

You will need to do multiple injections / instances before the actual test:

  • Initialize application
  • Entering $controller

    , $rootScope

    , $httpBackend

    andbookService

  • Create scopes for firstController and SecondController and store them in a variable
  • Store bookService

    and $httpBackend

    in variables
  • Create controller settings and save them

Then in the actual test, you have to tell $httpBackend

what to do when it caches the request for books (or books). Construct $httpBackend.whenGET("/api/books/1").passThrough();

will pass the request from the url "/api/books/1"

to the server. Then you need to set the property selectedRows

to firstScope

so that it fulfills the condition in the function selectGridRow

in your firstCtrl

.



Now you can call the function selectGridRow

to invoke the broadcast and API call. But you have to wrap it in a function runs

for Jasmine to recognize it as an asynchronous call and wait for it to complete. Waiting is defined in the call waitsFor

. It will wait for it to receive the book and it waits for a maximum of 5000ms, then the test will be marked as a failure.

The last step is to check the expected result. We don't need to validate anymore undefined

as the test won't get here anyway. The check must be wrapped in a call again runs

so that it can be executed after a successful "wait".

Here's the complete 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);
        });
    });

});

      

+1


source







All Articles