【问题标题】:async testing angular controller and services with jasmine用茉莉花异步测试角度控制器和服务
【发布时间】:2015-05-06 21:09:17
【问题描述】:

我刚刚开始使用Angular。我真的很喜欢这个设计,它实际上非常好测试。我似乎无法正常工作的一件事是测试asynchronous services 及其与controllers 的连接。
只是为了确保我确实理解了 Angulars $q,如果我的 service 看起来像这样;

 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 功能),但我似乎无法使其工作,这些是我面临的问题:: p>

  1. 在我的 服务 中,expect 永远不会被调用(或者更准确地说是过早调用,因为调试时结果是正确的)
  2. 或者当我在模拟控制器中使用茉莉花done(例如在.then 中)时,它总是超时并且永远不会被调用。
  3. 当使用 Angular 的单元测试示例中描述的方式时,调用 $rootScope.$apply 对我没有任何作用,并且再次出现问题 1。

所以,如果您能给我一些关于如何普遍处理此问题的提示,我将非常高兴。

【问题讨论】:

  • 你能展示一下你目前的测试吗?

标签: angularjs unit-testing testing asynchronous jasmine


【解决方案1】:

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

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 中定义代理。在运行测试的浏览器中观察控制台以获得更多线索。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-09
    • 2013-06-16
    • 2017-05-02
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多