角/茉莉测试与许诺递延 [英] Angular/Jasmine testing with deffered promises

查看:153
本文介绍了角/茉莉测试与许诺递延的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我测试使用的角度和茉莉花组合的控制器,并且我不能完全确定如何使用递延承诺。

这是我的天赋code。

 描述(控制器测试,函数(){
    VAR范围,searchAPI;    beforeEach(函数(){
        变种mockSearchAPI = {};
        模块('对myApp',函数($提供){
            $ provide.value('searchAPI',mockSearchAPI);
        });
    });    注(函数($ Q){
        VAR TESTDATA = {消息:喜};
        mockSearchAPI.executeSearch =功能(){
            变种延迟= $ q.defer();
            defer.resolve(TESTDATA);
            返回defer.promise;
        };
    });    beforeEach(主搜索控制器测试,函数(){        功能($控制器,$ rootScope,_searchAPI _){
            范围= $ rootScope $新的()。
            sea​​rchAPI = _searchAPI_;
            $控制器('MainSearchCtrl',函数(){
                $适用范围:适用范围,
                sea​​rchAPI:searchAPI
            });
            范围$摘要()。
        }
    });    它('要正确返回一个承诺',函数(){
        VAR字段=testfield;
        VAR值=testvalue;
        VAR PAGENUMBER = 1;
        VAR承诺= scope.processQueryByField(场,价值PAGENUMBER);        //此行给我'{}'
        警报(承诺);
    });});

我不确定为什么我提醒是给我的'{}'输出线。难道不应该是我在注射功能定义为TESTDATA的数据结构?我不知道是怎么回事。我曾尝试多种解决方案。

我的控制器code是基本的服务的包装

  $ scope.processQueryByField =功能(场,价值,PAGENUMBER){
    返回searchAPI.executeSearch(场,价值PAGENUMBER);
}

我不应该只是被接受,我喷油器code里面定义的值?


解决方案

我不是很确定要与承诺对象来设置有何期待,你并不需要测试,如果承诺得到解决,而不是你需要测试发生了什么数据的的承诺已得到解决。

例如: -

更改您的模拟,以简化: -

 注入(函数($ Q){
    VAR TESTDATA = {消息:喜};
    mockSearchAPI.executeSearch =功能(){
       返回$ q.when(TESTDATA);
    };
});

-

只是一个演示中,我已经在你的控制器,它解析为数据增加了一个方法

  .controller('MainSearchCtrl',['$范围,searchAPI',函数($范围,searchAPI){
        //此时放置在范围这个方法是没用的
        $ scope.processQueryByField =功能(场,价值,PAGENUMBER){
           返回searchAPI.executeSearch(场,价值PAGENUMBER);
        }
        //调用将更新模型中的SearchResult时,这。
        $ scope.populateData =功能(){
          $ scope.processQueryByField(1,1,1)。然后(功能(数据){
            $ scope.searchResults =数据;
          })
        }
    }]);

展望#1: - 测试是否被调用方法时API方法是越来越调用与预期的参数

 它('应该调用执行搜索'功能(){
     //设置一个窥视你的模拟API方法
      spyOn(mockSearchAPI,'executeSearch');
      VAR字段=testfield;
      VAR值=testvalue;
      VAR PAGENUMBER = 1;
      scope.processQueryByField(场,价值PAGENUMBER); //调用与ARGS范围的方法
      //如果测试模拟API方法被调用
      期待(mockSearchAPI.executeSearch).toHaveBeenCalled();
      //测试,如果它被称为预计参数。
      期待(mockSearchAPI.executeSearch).toHaveBeenCalledWith(场,价值PAGENUMBER);
    });

期望#2: - 测试数据是否正确填充时承诺解决

 它('要正确返回一个承诺',函数(){
    VAR字段=testfield;
    VAR值=testvalue;
    VAR PAGENUMBER = 1;    VAR承诺= scope.processQueryByField(场,价值PAGENUMBER);
    //这是一个无用的期望
    期待(承诺).toBeDefined();
    scope.populateData();
    $ rootScope $摘要()。 //< - 应用消化周期,使承诺得到解决
    期待(scope.searchResults).toBeDefined();
    期待(scope.searchResults.message).toEqual(HI);
});

测试演示

I am testing a controller using a combination of angular and jasmine, and am not completely sure about using deffered promises.

This is my spec code.

describe('Controller Tests', function(){
    var scope, searchAPI;

    beforeEach(function(){
        var mockSearchAPI = {};
        module('myApp', function($provide){
            $provide.value('searchAPI', mockSearchAPI);
        });
    });

    inject(function($q){
        var testData = {"message":"hi"};
        mockSearchAPI.executeSearch = function(){
            var defer = $q.defer();
            defer.resolve(testData);
            return defer.promise;
        };
    });

    beforeEach('Main Search Controller Tests', function(){

        function($controller, $rootScope, _searchAPI_){
            scope = $rootScope.$new();
            searchAPI = _searchAPI_;
            $controller('MainSearchCtrl', function(){
                $scope: scope,
                searchAPI: searchAPI
            });
            scope.$digest();
        }
    });

    it('should return a promise correctly', function(){
        var field = "testfield";
        var value = "testvalue";
        var pageNumber = 1;
        var promise = scope.processQueryByField(field, value, pageNumber);

        //THIS LINE IS GIVING ME '{}'
        alert(promise); 
    });

});

I am unsure why the line that I am "alerting" is giving me output of '{}'. Shouldn't it be the data struct that I defined as "testData" in the inject function? I am not sure what is going on here. I have tried numerous solutions.

My controller code is basically a wrapper for the service

$scope.processQueryByField = function(field, value, pageNumber){
    return searchAPI.executeSearch(field, value, pageNumber);
}

Shouldn't I just be receiving the value that I defined inside the injector code?

解决方案

I am not exactly sure what expectation you want to set with the promise object, You do not need to test if a promise is resolved, instead you need to test what happens to the data when a promise is resolved.

Example:-

Change your mock to simplify:-

inject(function($q){
    var testData = {"message":"hi"};
    mockSearchAPI.executeSearch = function(){
       return $q.when(testData);
    };
});

Just for a demo i have added one more method in your controller which resolved to a data:-

.controller('MainSearchCtrl', ['$scope','searchAPI', function ($scope, searchAPI) {
        //At this point placing this method on scope is useless
        $scope.processQueryByField = function(field, value, pageNumber){
           return searchAPI.executeSearch(field, value, pageNumber);
        }
        //This when invoked will update the searchResults in the model.
        $scope.populateData = function(){
          $scope.processQueryByField(1,1,1).then(function(data){
            $scope.searchResults = data;
          })
        }
    }]);

Expectation #1:- Test whether when the method is invoked the api method is getting invoked with the expected arguments.

   it('should invoke execute search', function(){
     //Set up a spy on your mock api method
      spyOn(mockSearchAPI,'executeSearch'); 
      var field = "testfield";
      var value = "testvalue";
      var pageNumber = 1;
      scope.processQueryByField(field, value, pageNumber); //invoke scope method with args
      //Test if the mock api method has been called
      expect(mockSearchAPI.executeSearch).toHaveBeenCalled();          
      //test if it has been called with expected arguments.
      expect(mockSearchAPI.executeSearch).toHaveBeenCalledWith(field, value, pageNumber); 
    });

Expectation #2:- Test whether data is populated properly when the promise is resolved.

it('should return a promise correctly', function(){
    var field = "testfield";
    var value = "testvalue";
    var pageNumber = 1;

    var promise = scope.processQueryByField(field, value, pageNumber);
    //This is a useless expectation
    expect(promise).toBeDefined();


    scope.populateData();
    $rootScope.$digest(); //<-- Apply digest cycle, so the promise is resolved
    expect(scope.searchResults).toBeDefined();
    expect(scope.searchResults.message).toEqual("hi");
});

Test Demo

这篇关于角/茉莉测试与许诺递延的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆