Amarsh Amarsh - 5 months ago 8
AngularJS Question

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

Answer

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