【问题标题】:Get function return value inside promise on spyOn service - Jasmine Angularjs在 spyOn 服务的 Promise 中获取函数返回值 - Jasmine Angularjs
【发布时间】:2018-02-14 18:09:29
【问题描述】:

我正在测试一个从 Promise 接收值并将这个值(字符串)连接到 url 的函数。函数的实现就ok了。

  var resp = {"payment": {
    "additional_information": {
      "skuSeatIds": "[{\"sku\":\"5234\",\"Description\":\"Advanced\",\"seatId\":792}]"
    }}};


   var promise = Promise.resolve(JSON.parse(resp.payment.additional_information.skuSeatIds));
   var update = spyOn(doneService, 'getOrderInfo').and.returnValue(promise);


   var url = controller.setSeatIdLink();
   expect(url).toBe('http://localhost:4000/#!/search?type=Selector&seatId=792');
});

然后我有调用 doneService.getOrderInfo() 的函数

  function setSeatIdLink () {
    doneService.getOrderInfo(store.get('orderId')).then(function(resp){
           var stri = vm.modalSelectorUrl.concat(resp[0].seatId);
            vm.modalSelectorUrl = stri;
            return vm.modalSelectorUrl;
    });
  }

vm.modalSelectorUrl 正确设置了 url。 spyOn 返回值很好。如果我记录“vm.modalSelectorUrl”,那么 url 就可以了。但是我在期望(url)上没有定义......

如果我在 .then(function(){ ... 范围之外对返回进行硬编码,则返回有效。

有什么想法吗?谢谢!

【问题讨论】:

    标签: javascript angularjs unit-testing jasmine karma-runner


    【解决方案1】:

    这里你的函数setSeatIdLink没有返回任何东西。 Return 语句在 then 函数内,而不是在 setSeatIdLink 函数内。 这就是它返回存储在url 中的undefined 的原因。

    尝试断言vm.modalSelectorUrl

    function setSeatIdLink () {
        doneService.getOrderInfo(store.get('orderId')).then(function(resp){
               var stri = vm.modalSelectorUrl.concat(resp[0].seatId);
                vm.modalSelectorUrl = stri;
                return vm.modalSelectorUrl;
        });
      }
    

    更新

    像这样改变你的功能

    function setSeatIdLink() {
        var defer = $q.defer();
        doneService.getOrderInfo(store.get('orderId')).then(function (resp) {
            var stri = vm.modalSelectorUrl.concat(resp[0].seatId);
            vm.modalSelectorUrl = stri;
            defer.resolve(vm.modalSelectorUrl);
        });
        return defer.promise;
    }
    

    还有这样的测试用例

    it('testcase', function (done) {
        //your code
        var url = controller.setSeatIdLink().then(function (url) {
            expect(url).toBe('http://localhost:4000/#!/search?type=Selector&seatId=792');
            done();
        });
        $scope.$apply();
    });
    

    【讨论】:

    • 感谢您的回复。如果我断言 vm.modalSelectorUrl 我得到没有连接的原始值。 @ashish
    • 我编辑了上面的代码,现在我收到了这个错误:错误:超时 - 在 jasmine.DEFAULT_TIMEOUT_INTERVAL 指定的超时内未调用异步回调
    • 尝试在测试用例中controller.setSeatIdLink()调用后添加scope.$apply()
    • 同样的事情。我想知道是否有办法检查函数内部是否按预期设置了变量。因为这将非常有帮助,如果给出响应,逻辑会将变量设置为应有的状态。
    【解决方案2】:

    您需要返回一个返回承诺的函数。如果您使用 AngularJS,最好坚持使用 $q,尽管我相信无论哪种方式都可以正常工作。

    var mock_func = function(data) {
       return $q.resolve(data);
    };
    
    spyOn(func, 'method').and.callFake(mock_func({
       data: 'to_return'
    }));
    

    【讨论】:

      猜你喜欢
      • 2016-05-12
      • 1970-01-01
      • 2015-08-22
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多