2016-01-14 31 views
0

我有一个需要测试的角度控制器。此控制器调用服务以从服务器检索数据。该服务返回ES6承诺。与ES6的同步/捕捉方法茉莉花的约定

function MyController($scope, MyService) { 
    $scope.doSomething = function() { 
    MyService.foo().then() { 
     whatever...; 
    }; 
    }; 
}; 

在我的茉莉花测试,我嘲笑这也返回承诺服务:

​​

我手动调用全球决心(或拒绝)带或不带参数来检查我的控制器上。

it('shall call the service', function() { 
    $scope = $rootScope.$new(); 
    controller = $controller('MyService', { $scope: $scope }); 
    controller.doSomething(); 
    myService.resolve(); 
    expect(whatever...); 
}); 

问题是解析调用是异步的。所以我正在测试我的预期结果,同时运行then函数。

我试图返回一个简单的自定义对象,将解析作为一个同步调用,但事实证明Promise有一些特定的规则,在模拟中重新实现会非常麻烦(比如当你有时。 ().catch()。然后模式)。

有没有办法在Jasmine中以简单同步的方式测试这种事情?

+1

只是不要试图使承诺同步。即使在您的测试套件中,嵌入异步也是如此。 – Bergi

回答

2

你需要告诉Jasmine你的测试是异步的,它应该等待它完成,然后再决定它失败。

it('shall call the service', function (done) { 
    $scope = $rootScope.$new(); 
    controller = $controller('MyService', { $scope: $scope }); 
    var promise = 
    controller.doSomething() 
     .then(function() { 
     expect(whatever...); 
     done(); 
     }); 

    myService.resolve(); 
}); 

更简单的方法,使您的嘲弄自动解析是使用Promise.resolve方法:你可以通过添加一个done参数,以此来规范声明(it调用),并在您的期望结束通话done做到这一点:

然后,您不需要调用myService.resolve - 模拟自动返回解析的承诺。

我最近开始使用jasmine-promises模块,这使得编写promise调用变得更加容易 - 并确保如果promise拒绝,报告错误和调用堆栈,以便于调试。与jasmine-promises这只会变成:

it('shall call the service', function() { 
    $scope = $rootScope.$new(); 
    controller = $controller('MyService', { $scope: $scope }); 

    return controller.doSomething() 
     .then(function() { 
     expect(whatever...); 
     }); 
});