角度单元测试状态滤波器

时间:2015-07-31 15:43:08

标签: angularjs unit-testing

我有一个依赖于服务来检索某些配置的过滤器,因此我使过滤器有状态。它很棒!但是,我想在它周围添加单元测试,但无法解决如何实现它们。

示例过滤器:

.filter("myFilter", function(myService) {
  var data = null, serviceInvoked = false;

  function realFilter(value) {
    return data + value;
  }

  filterStub.$stateful = true;
  function filterStub(value) {
    if( data === null ) {
      if( !serviceInvoked ) {
        console.log('no state'); // dirty console.log for unit test diagnostics
        serviceInvoked = true;
        myService.get().then(function(result){
           data = result;
        });
      }
      return "-";
    }
    else {
      return realFilter(value);
    }
  }

  return filterStub;
});

我可以测试最初返回“ - ”。

在我的下一个测试中,我使用sinonjs存储 myService 并返回一个promise。我想用数据解决该承诺,并看到过滤器正确更新。我的测试看起来像:

it('returns the value prepended with the data from the service', 
  function () {
    $scope.value = "World!";
    var markup = "<div>{{value | myFilter}}</div>";
    var element = $compile(markup)($scope);
    $scope.$digest();
    /*
     * Works:
     */
    expect(element.html()).toBe('-');

    /*
     * the following still returns "-" though I want to test 
     * that realFilter was executed
     */
    myServiceMock_getPromise.resolve('Hello ');
    $scope.$digest();

    // FAIL: Expected '-' to be 'Hello World!'
    expect(element.html()).toBe('Hello World!');
});

这在生产中有效,但在单元测试中,过滤器中的console.log使用每个摘要输出“无状态”,暗示不保持过滤器状态。

我是否正在编写标记的方式,以至于无法保持状态或我的测试出错?

1 个答案:

答案 0 :(得分:1)

它与模板编译无关。这是关于承诺和javascript滴答声。

已解决的承诺将以不同的刻度执行(无论$scope.$digest只启动此过程)。因此,期望应该包含在.then中,并且应该通过done回调通知测试引擎该测试是异步的。

it('returns the value prepended with the data from the service', 
  function (done) {
    ...

    myServiceMock_getPromise.resolve('Hello ');
    $scope.$digest();
    myServiceMock_getPromise.promise.then(function(){
       expect(element.html()).toBe('Hello World!');
       done();
    });
 }