【问题标题】:Handling failed promises in jasmine处理茉莉花中的失败承诺
【发布时间】:2016-10-26 16:33:06
【问题描述】:

我是茉莉花的新手!

我有以下代码的服务

function getSomeData() { 
            return $http(
                    {
                        method: 'GET',
                        url: $localStorage.serverName + 'w_service_json.get_wf_proc?pn_login_id='  + sessionService.getUserId()
                    }).then(function (response) {
                                var lv_json = JSON.stringify(response.data);
                                var myArr = JSON.parse(lv_json);
                                return myArr;
                            }).catch(function (err) {//console.log(err);
                                var val = err.message || (err.status==-1?'server error':'error');
                                errService.add(val);
                                return err; 
                            });
        }

还有一个错误处理服务(errService)如下:

angular
        .module('err')
        .service('errService', errService);

    errService.$inject = ['$mdDialog'];
    function errService($mdDialog) {
        var self = this;
        var erros=[];
        self.add = add;
        self.show = show;

        return self;

        function add(err)
        {
            erros.push(err);
            throw err;
        }

我需要确保服务正在处理错误,所以我在 jasmine 中进行了测试:

beforeEach(inject(function (_errService_,_$rootScope_,_sessionService_,_wfActivitiesRemoteService_,_$localStorage_,_$state_, $httpBackend) {

    $scope=_$rootScope_;
    errService=_errService_;
    wfActivitiesRemoteService = _wfActivitiesRemoteService_;
    state=_$state_;
    $localStorage=_$localStorage_;
    $localStorage.serverName="http://someserverip/";
    sessionService=_sessionService_;
    httpBackend = $httpBackend;
    httpBackend.whenGET(/\.html$/).passThrough();

  }));

  it("sem sessao", function () {

    spyOn(sessionService, "getUserId").and.returnValue("");

    httpBackend.expectGET('http://someserverip/w_service_json.get_wf_proc?pn_login_id=').respond(-1,errServer);

    var test=function(data)
    {
          expect(data).toEqual('');
          console.log("test");
    };
    var fail=function(err)
    {
        expect(err).not.toBeUndefined();
        console.log("fail");
    };   

    var run=function()
    {
        wfActivitiesRemoteService.getSomeData().then(test).catch(fail);
    };

    expect(function() {wfActivitiesRemoteService.getSomeData}).toThrow('server error');
    run();

    httpBackend.flush();


});

我无法进入函数内部失败!服务中的promise失败,测试自动失败,没有在测试里面输入catch!

我该如何解决这个问题? 解决这个问题的正确方法是什么?

【问题讨论】:

  • 正确的做法是使用$httpBackend.whenGET() 并告诉它如何响应以便它击中你的捕获。 docs.angularjs.org/api/ngMock/service/$httpBackend#whenGET
  • toThrow 断言的使用不正确(除了那里没有调用 getSomeData 的事实)。被拒绝的承诺不会抛出。
  • getSomeData 没有被调用,因为一个错字。对不起!
  • 如果我使用 whenGet 而不是 expectGet 它不会等待调用退出之前的测试,它不会接受 http.flush 并在没有输入任何功能的情况下给我一个错误的成功。 ng-learn.org/2014/08/Testing_Promises_with_Jasmine
  • 没想到会抛出我得到这个:test sem sessao FAILED server error throw。期待我得到:test sem sessao FAILED Expected function to throw an exception.ServiceSpec.js:118:40 loaded@localhost:9876/context.js:151:17 server error throw

标签: angularjs jasmine karma-runner


【解决方案1】:

我找到了解决方案!异常需要在测试中捕获,而不是在承诺中!所以我不得不将代码更改为:

var test=function(data)
    {
        console.log("test:"+data);  
        expect(data).toEqual('');

    };
    var fail=function(err)
    {
        console.log("fail");
        expect(err).not.toBeUndefined();
        expect(err).toEqual('server error');

    };   
    var run=function()
    {
        console.log('run');
        wfActivitiesRemoteService.getSomeData().then(test).finally(done);
    };
    try
    {
        spyOn(sessionService, "getUserId").and.returnValue("");

        httpBackend.expectGET('http://someserverip/w_service_json.get_wf_proc?pn_login_id=').respond(-1,errServer);
        run();
        httpBackend.flush();
    }
    catch(err)
    {
        console.log("catch");
        fail(err);
    }
    finally
    {
        console.log("finally");
        done();
    }

我仍然认为可能有一种方法可以用 Promise 对其进行测试,但是通过这种方式我已经能够捕获并测试错误。

【讨论】:

  • 我认为您可以删除.finally(done),因为您会在catch 之后在finally {...} 上调用它。确认这一点的一些专家将非常感激
猜你喜欢
  • 1970-01-01
  • 2016-04-24
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2021-05-25
  • 1970-01-01
相关资源
最近更新 更多