AngularJS : Testing directive, HTML not re-rendered after promise completion

强颜欢笑 提交于 2019-12-11 19:07:14

问题


I am writing some basic unit tests for my AngularJS app. I have some bindings on the UI with a scope variable inside my directive whichis populated on the completion of a promise.

HTML:

<div id="parent">
   <div id="child" ng-repeat="l in aud">
      // Other Stuff
   </div>
</div>

Directive:

link: function(scope){
  service.getArray().$promise.then(function(data){
   scope.aud = data;
}

Test:

describe('my module', function () {
    var $compile: ICompileService, $rootScope: IScope, directive: JQuery<HTMLElement>;

    // Load the myApp module, which contains the directive
    beforeEach(angular.mock.module('my-module'));
    beforeEach(angular.mock.module(($provide) => {

        $provide.service('service', () => {
            return {
                getArray: () => {
                    return Promise.resolve(
                        ["item1", "item2"]
                    );
                }
            }
        });


        // Store references to $rootScope and $compile
        // so they are available to all tests in this describe block
        beforeEach(inject(($httpBackend: IHttpBackendService, _$compile_: ICompileService, _$rootScope_: IRootScopeService) => {
            $compile = _$compile_;
            $rootScope = _$rootScope_.$new();
            directive = $compile('<my-directive></my-directive>')($rootScope)
            $rootScope.$apply();
        }));

        describe('account-utility directive', function () {
            it('account utility directive details panel is shown on click', function () {
                let list = directive.find("parent"); // Finds this
                let listItems = list.find("child"); // Cannot find this. Throws error. 
                console.log(list); // innerHTML still shows ngrepeat unsubstituted by divs
                expect(listItems.length).toBe(2);
            });
        });

});

I debugged the whole thing and the promise is resolved and the data is assigned to the scope variable 'aud'. However seems like my copy of scope for the test and the app are different. Whats going on here?


回答1:


When the Angular's promise is resolved you need to notify it so it will run its dirty check.

In order to do that you need to invoke $rootScope.apply() inside yours it clause.

Think of it like that, your $rootScope.apply() call in the before each clause invokes your directive's link function, the that function registers a Promise resolvment in Angulars queue, but it not got processed.




回答2:


beforeEach((done) => {
        directive = $compile('<my-directive></my-directive>')($rootScope);
        $rootScope.$digest();

        setTimeout(() => {
            $rootScope.$digest();
            done();
        });
    });

Done helps you wait till all asynchronous tasks are picked up from the stack.

apply()

works too



来源:https://stackoverflow.com/questions/58110497/angularjs-testing-directive-html-not-re-rendered-after-promise-completion

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!