为什么我的茉莉花测试失败了我的Angular应用程序

时间:2016-06-26 02:43:43

标签: angularjs jasmine httpbackend

我有以下代码......其中一个测试失败了。请帮助我理解原因,并建议我纠正的方法。

<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>

编辑:问题是在第二次测试中,我想在发出虚假的http请求之前以某种方式设置$scope.searchString = "r"。我不知道该怎么做。

错误是:

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

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

3 个答案:

答案 0 :(得分:1)

修改代码的设计

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

现在正在进行的测试失败:

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

工作代码:http://codepen.io/gpincheiraa/pen/pbRKMZ

答案 1 :(得分:0)

我看到的直接问题是这个,

beforeEach(inject(function(_$controller_, _$httpBackend_, _$rootScope_) {
    $controller = _$controller_;
    scope = _$rootScope_.$new();

您应该从$ rootScope创建新范围。

<强>更新

如果这没有帮助,请分享您得到的错误。

it('should show only Rory for query=r', function () {
    $httpBackend.expectGET('/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
    $httpBackend.expectGET('/findusers?q=r').respond(['Rory']);

    $controller('peopleSearchCtrl', {$scope: $scope});

    $scope.searchString = 'r';
    $scope.textChanged();    
    $httpBackend.flush();

    expect($scope.users).toEqual(['Rory']);
});

请检查这是否有帮助。

Codepen工作 http://codepen.io/anon/pen/ezgjOx

答案 2 :(得分:0)

我在附加的代码中观察到了几个问题: 1.为每个不正确的测试实例化$ controller。控制器应该在顶层实例化,我们应该在任何需要的地方使用该控制器实例。这样我们就可以减少代码重复并缩短测试执行时间。

  1. 您已添加$ scope.searchString =&#34;&#34 ;;执行$ scope.textChanged()之前的行;从编码角度来看,这看起来不太好。在textChanged()本身,我们应该检查$ scope.searchString是空白还是未定义,并根据它创建Rest URL。

  2. 在第二次测试中,我们必须将以下行放在开头: httpBackend.when(&#39; GET&#39;,&#39; / findusers?q =&#39;)                         .respond([&#39;肖恩&#39;&#39;偏航&#39;&#39;露&#39;&#39;埃里克&#39;&#39;罗里&#39;,& #39; Heyley&#39;]);否则它会抱怨/ findusers的问题?q = url

  3. 我已经修改了上面的代码并使其现在正常工作:

    <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>
    </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
                var searchUsers = ($scope.searchString) ? $scope.searchString.trim(): "";
    
                $http.get('/findusers?q=' + searchUsers).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.textChanged();
        });
    
        describe('search people app tests', function () {
    
            var controller, httpBackend, scope;
    
            // setup before each test run
            beforeEach(module('peoplesearchApp'));
            beforeEach(inject(function (_$controller_, _$httpBackend_, _$rootScope_) {
                scope = _$rootScope_.$new();
                httpBackend = _$httpBackend_;
    
                controller = _$controller_('peopleSearchCtrl', {$scope: scope});
            }));
    
            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.when('GET', '/findusers?q=').respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
    
                    scope.textChanged();
                    httpBackend.flush();
                    expect(scope.users).toEqual(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
                });
    
                it('should show only Rory for query=r', function () {
                    httpBackend.when('GET', '/findusers?q=')
                            .respond(['Sean','Yaw','Lucy','Eric','Rory','Heyley']);
    
                    scope.searchString = 'r'; 
    
                    httpBackend.when('GET', '/findusers?q=r')
                            .respond(['Rory']);
                    scope.textChanged();
                    httpBackend.flush();
                    expect(scope.users).toEqual(['Rory']);
                });
            });
    
        })
    
    </script>
    </html>
    

    我希望它能解决你的问题。

    干杯!