Heather Roberts
Heather Roberts

Reputation: 2138

How to test a directive which uses ngModel on same element

I have a directive which requires ngModel. In its link function it calls $setViewValue on the ngModel controller. I want to test that $setViewValue is being called under the right conditions, but I can't work out how to add my spy...

Here is my simplified code:

directive

angular.module("myApp").directive("myDir", function()
{
    return {
        restrict: "A",
        require: ["ngModel"],
        link: function(scope, element, attrs, ctrls)
        {
            var ngModel = ctrls[0];

            ......

            function changeHandler(event) {
                ngModel.$setViewValue(ckeditor.getData());
            }
        }
    };
});

html:

<textarea my-dir ng-model="myData"></textarea>

and I want my test to be something like:

describe("updating text in ckeditor", function() {
        it("should update model value", function() {
                $compile("<textarea my-dir ng-model='text'></textarea>")(scope);
                spyOn(ngModel, "$setViewValue");
                // trigger change handler
                expect(ngModel.$setViewValue).toHaveBeenCalled();
        });
});

Thanks!

Upvotes: 1

Views: 691

Answers (1)

Heather Roberts
Heather Roberts

Reputation: 2138

I couldn't really find how to mock ngModel in the link function but I found an alternative approach for how I could test this, which is much better anyway and I'll post in case it helps someone.

So rather than spy on the $setViewValue function, I just test the value has changed on the property passed in as the value of ngModel. Seems so obvious really.

Anyway, here is my test

describe("updating text in ckeditor", function() {
        it("should update model value", function() {
                scope = $rootScope.$new();
                scope.text = "";
                $compile("<textarea my-dir ng-model='text'></textarea>")(scope);

                spyOn(ckeditorInstance, "getData").and.returnValue("updated text");
                // trigger change handler...

                expect(scope.text).toEqual("updated text");
        });
});

Upvotes: 0

Related Questions