Search code examples
angularjsjasminehttpbackend

Why is my jasmine test failing for my Angular app


I have the following code ... and one of the tests is failing. Please help me in understanding why, and suggest me a way to rectify.

<html>
<head>
    <!-- Jasmine References -->
    <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/jasmine-html.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.3.3/boot.min.js"></script>
    <!-- Angular and Angular Mock references -->
    <script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular.min.js"></script>
    <script type="text/javascript" src="https://code.angularjs.org/1.4.0-rc.2/angular-mocks.js"></script>
    <!-- The code we need to test -->
    <script type="text/javascript" src="/js/index.js"></script>
</head>
<body></body>
<script type="text/javascript">

    var app = angular.module('peoplesearchApp',[]);

    app.controller('peopleSearchCtrl',function($scope,$http){
        $scope.textChanged = function() {
            // obtain the list of user whose name have the given prefix
            $http.get('/findusers?q='+$scope.searchString.trim()).success(function(data, status) {
                $scope.users = data;
            }).error(function(data, status) {
                console.log("Error: could not retrieve users");
            });
        };
        // make an initial call to retrieve all users
        $scope.searchString = "";
        $scope.textChanged();
    });

    describe('search people app tests', function () {

        var $controller, $httpBackend, $scope;

        // setup before each test run
        beforeEach(module('peoplesearchApp'));
        beforeEach(inject(function (_$controller_, _$httpBackend_) {
            $controller = _$controller_;
            $scope = {};
            $httpBackend = _$httpBackend_;
        }));

        describe('only the users that have their names starting from the search query should be visible', function () {

            it('should show all users for a blank query', function () {
                $httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
                $controller('peopleSearchCtrl', {$scope: $scope});
                $httpBackend.flush();
                expect($scope.users).toEqual(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
            });

            it('should show only Rory for query=r', function () {
                $httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
                $controller('peopleSearchCtrl', {$scope: $scope});
                $httpBackend.flush();
                expect($scope.users).toEqual(['Rory']);
            });

        });

    })

</script>
</html>

EDIT: The issue is that in the second test, I want to set $scope.searchString = "r" somehow before issuing a fake http request. I dont know how to do that.

The Error is:

Error: Unexpected request: GET /findusers?q=
Expected GET /findusers?q=r

CodePen : http://codepen.io/amarshanand/pen/MeJXdq


Solution

  • Modifying a little bit the design of your code

    app.controller('peopleSearchCtrl',function($scope,$http){
              console.log($scope);  
    
              $scope.textChanged = function(_searched) {
                    // obtain the list of user whose name have the given prefix
                    $http.get('/findusers?q='+_searched.trim()).success(function(data, status) {
                        $scope.users = data;
                    }).error(function(data, status) {
                        console.log("Error: could not retrieve users");
                    });
                };
                // make an initial call to retrieve all users
                $scope.searchString = "";
                $scope.textChanged($scope.searchString);
            });
    

    The failed test it's working now:

    it('should show only Rory for query=r', function () {     //faking the initialize call of the controller  
                      $httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
                        $httpBackend.expectGET('/findusers?q=r').respond(['Rory']);
                        $controller('peopleSearchCtrl', {$scope: $scope});
                        $scope.textChanged('r');
                        $httpBackend.flush();
                        expect($scope.users).toEqual(['Rory']);
                    });
    

    Working codepen: http://codepen.io/gpincheiraa/pen/pbRKMZ