使用jasmine

时间:2015-05-06 21:09:17

标签: angularjs unit-testing testing asynchronous jasmine

我刚开始使用Angular。我非常喜欢这个设计,测试它真的很不错。我无法做到的一件事就是测试asynchronous services及其与controllers的连接。
只是为了确保我确实理解了Angulars $q,如果我的服务看起来像这样;

 this.AsyncTask = function (params) {
        var deferred = $q.defer();
        doAsyncStuff(params, function () {
            if (iAmReady) {
                deferred.resolve("Success");
            }
        });
        return deferred.promise;
    };  

在我看来,这基本上做了以下几点。做异步的东西并返回一个promise(它正在处理异步的东西)。在某个时刻处理事件时,"通知"承诺异步任务完成并返回一些值。现在在我的控制器中我会这样做。

MyService.AsyncTask(params).then(function (value) {
    if (value) {
        $scope.success = value;
    }
});

这里控制器指示服务执行AsyncTask(带有一些参数),.then告诉服务完成异步任务,控制器可以根据该结果做一些逻辑。 /> 到目前为止一直很好,这实际上在制作中完全符合我的要求,但是我无法使用jasmine对其进行单元测试。
我尝试了很多可能的解决方案(包括Angulars official example on that以及jasmines done功能)但我似乎无法使其工作,这些是我面临的问题< / strong>:

  1. 在我的服务中,expect 永远不会被调用(或者更准确地说,由于调试时结果是正确的,因此过早调用)
  2. 或者当我在我的模拟控制器中使用jasmines done(例如在.then内)时,它总是超时并且永远不会被调用。
  3. 当使用Angular的单元测试示例中描述的方式时,调用$rootScope.$apply对我和问题1都没有做任何事情。
  4. 所以如果你能给我一些关于如何做到这一点的提示,我会很高兴的。

1 个答案:

答案 0 :(得分:0)

在不知道您描述的每个问题的测试代码的情况下,通常您可以像这样测试异步服务:

describe('service', function() {
  // alter to match your module name
  beforeEach(module('myApp.services'));

  it('should test async calls', function (done) {
    //inject your services
    inject(function(MyService) {
      MyService.AsyncTask({/*your params*/})
        .then(function (result) {
          expect(result).toBeDefined();
          // add more tests
          done();
        }).catch(function (err) {
          // don't forget this. If something goes wrong, you wanna know 
          // why and don't run into a non-saying timeout error
          fail('Failure during AsyncTask: ' + err);
          done(); // important so that the runner knows the test is over
                  // even if it failed
        });
    });
  });
});

当您使用Jasmine 2.0运行异步测试时,需要在完成测试后调用done方法。如果默认超时不足以进行测试,则可以为单个测试定义超时:

it('should ...', function(done) { ... }, 10000); // timeout set to 10 sec

关于您的问题的更多想法:如果doAsyncStuff联系到服务器,您可能需要模拟它或在karma config中定义代理。在浏览器中观察运行测试的控制台,以获得更多线索。