难以测试状态使用ui-router状态配置调用

时间:2016-05-24 12:00:03

标签: angularjs angular-ui-router

我正在使用ui-router并在我的路由器配置中定义了几个状态

.state('operator', {
    url: '/operator/:operatorId',
    parent: 'common',
    template: '<div ui-view></div>',
    controller: 'OperatorPageController',
    controllerAs: 'vm',
    resolve: {
        operator: getOperator
    }
}).state('operator.edit', {
    templateUrl: 'app/features/settlement/operators/edit/operator-edit.html',
    controller: 'OperatorEditController',
    controllerAs: 'vm'
});

//resolve in operator state calls this
getOperator.$inject = ['$stateParams', 'transportOperatorService'];
function getOperator($stateParams, transportOperatorService) {
    return transportOperatorService.get($stateParams.operatorId);
}

我现在正试图在单元测试中覆盖operator.edit状态。

describe('State Change: operator.edit', function() {
    var state = 'operator.edit',
      transportOperatorService,
      $q,
      deferredGet;
    beforeEach(inject(function(_transportOperatorService_, _$q_) {
      transportOperatorService = _transportOperatorService_;
      $q = _$q_;
      deferredGet = $q.defer();
      spyOn(transportOperatorService, 'get').and.returnValue(deferredGet.resolve);
      $httpBackend.expectGET('common.html').respond({});
      $httpBackend.expectGET('app/features/settlement/operators/edit/operator-edit.html').respond({});
    }));
    it('should resolve the operator.edit state view', function() {
      $state.go(state, {operatorId:12345);
      deferredGet.resolve();
      $httpBackend.flush();
      expect($state.current.name).toBe(state);
    });
  });
});

测试失败,对我在默认状态下定义的主页模板有一个意外的GET请求,所以也许这表明路由器无法解析我的operator.edit状态,但是当我的应用运行时状态确实有效。

任何人都可以通过我的测试设置看到任何可以解释这一点的明显内容吗?

我一直在指这个article

由于

更新

好的,所以我现在能够使用以下方法实现这一点

describe('State Change: operator.edit', function() {
    beforeEach(inject(function(_transportOperatorService_, $templateCache) {
      var transportOperatorService = _transportOperatorService_;
      spyOn(transportOperatorService, 'get').and.returnValue(deferred.promise);
      $templateCache.put('common.html', '');
      $templateCache.put('app/features/settlement/operators/edit/operator-edit.html', '');
    }));
    it('should resolve the operator.edit state view', function() {
      $state.go('operator.edit');
      deferred.resolve();
      $rootScope.$digest();
      expect($state.current.name).toBe('operator.edit');
    });
  });
});

所以差异在于我现在使用templateCache而不是httpBackend并调用摘要周期。但我不完全理解为什么这个测试有效,任何人都可以进一步解释这个流程吗?

3 个答案:

答案 0 :(得分:2)

不确定根本原因是什么,但在编辑器容器上使用*ngIf可解决此问题。请看看this-

handleTabChange(tabChangeEvent: { originalEvent: Event; index: number }) {
    if (tabChangeEvent.index === 0) {
      //this.monacoEditor.editor.layout();
      this.showEditor = true;
    } else {
      this.showEditor = false;
    }
  }

然后在您的模板中-

<div style="height: 500px" *ngIf="showEditor">
            <ngx-monaco-editor #monacoEditor style="height:100%;" [options]="editorOptions" [(ngModel)]="code">
            </ngx-monaco-editor>
        </div>

答案 1 :(得分:1)

首先,请注意,该问题与角度分量无关。 关于Monaco editor

摩纳哥如何找到其实际布局?

考虑一个在容器内具有可见摩纳哥编辑器的页面。加载Monaco编辑器后,它将根据可见视图设置布局大小。 那么,如果您在隐藏容器中请求对Monaco进行更新,会发生什么情况?显然,Monaco没有可见的视图来设置其布局道具。编辑器根据隐藏视图设置布局! 这就是为什么您看到点而不是区域的原因。现在,当该视图变为可见状态时,即使调用.layout()方法或设置{{1},编辑器也不会更新布局。 }在automaticLayout: true中。您可以通过调整浏览器大小,再次更新编辑器或一些 Angular技巧来触发。

现在您了解其工作原理。因此,请避免在不可见视图中更新摩纳哥。让此操作在包含视图后可见。

答案 2 :(得分:0)

使用 *ngIf 将初始化/销毁 ngx-monaco-editor 组件,这可能有用也可能没有用。

当我有一个包含 ngx-monaco-editor 的组件时,我会创建以下函数,每当我需要调整 monaco 编辑器的大小时都会调用该函数。

    resizeComponents() {
        setTimeout(() => {
            window.dispatchEvent(new Event('resize'));
        }, 200);
    }

使用示例:

查看

<div (click)="onTabChange('myTab')">Change Tab</div>

组件

onTabChange(myTab) {
   
    // execute tab change logic
    this.resizeComponents()
}

同样,这是一种替代方法,以防您不想重新初始化编辑器。