0

I am currently writing a service to control an upload flow. I am writing unit tests right now for the function which show and hide the upload modal box. In the tests, I am using angular.element.find to look to see if the modal exists. In the second test, the number goes up from what I would expect, as though it isn't resetting.

The two tests are as follows:

    describe('show', function() {
        it('should initially not show the modal', function() {
            expect(upload.isShowing()).toEqual(false);
            expect(angular.element.find('.modal').length).toEqual(0);
        });

        it('should show the upload modal', function() {
            expect(upload.isShowing()).toEqual(false);
            expect(angular.element.find('.modal').length).toEqual(0);

            upload.show();
            $rootScope.$digest();
            expect(upload.isShowing()).toEqual(true);
            expect(angular.element.find('.modal').length).toEqual(1);
        });
    });

    describe('cancel', function() {
        it('should hide the upload form', function() {
            expect(upload.isShowing()).toEqual(false);
            expect(angular.element.find('.modal').length).toEqual(0);

            upload.show();
            $rootScope.$digest();
            expect(upload.isShowing()).toEqual(true);
            expect(angular.element.find('.modal').length).toEqual(1);

        });
    });

The first describe block passes fine, but the second one fails. It tells me that it Expected 1 to equal 0. If I comment out the first expect with angular.element.find in the test for cancel it says 'Expected 2 to equal 1.'

All I can determine is that the html is all getting thrown into the same space, and is compounding after each test. Is there some way I can prevent this behaviour, or use an `afterEach' statement to flush the previous HTML?

Thanks!


Ammendment

Here is the full code for this suite of tests, if it helps:

describe('uploadService', function() {
    var $rootScope,
        upload;

    beforeEach(module('upload'));
    beforeEach(module('upload.service'));
    beforeEach(module('bublNg.templates'));
    beforeEach(module('ui.bootstrap.tpls'));

    beforeEach(inject(function($injector) {
        upload = $injector.get('upload');
        $rootScope = $injector.get('$rootScope');
    }));

    describe('isShowing', function() {
        it('should return true if the modal us showing', function() {
            expect(upload.isShowing()).toEqual(false);

            upload.show();
            expect(upload.isShowing()).toEqual(true);
        });
    });

    describe('show', function() {
        it('should initially not show the modal', function() {
            expect(upload.isShowing()).toEqual(false);
            expect(angular.element.find('.modal').length).toEqual(0);
        });

        it('should show the upload modal', function() {
            expect(upload.isShowing()).toEqual(false);
            expect(angular.element.find('.modal').length).toEqual(0);

            upload.show();
            $rootScope.$digest();
            expect(upload.isShowing()).toEqual(true);
            expect(angular.element.find('.modal').length).toEqual(1);
        });
    });

    describe('cancel', function() {
        it('should hide the upload form', function() {
            expect(upload.isShowing()).toEqual(false);
            // expect(angular.element.find('.modal').length).toEqual(0);

            upload.show();
            $rootScope.$digest();
            expect(upload.isShowing()).toEqual(true);
            // expect(angular.element.find('.modal').length).toEqual(1);
            upload.cancel();
            expect(upload.isShowing()).toEqual(false);

        });
    });
});
user2943490
  • 6,900
  • 2
  • 22
  • 38
Octothorpe
  • 175
  • 11

2 Answers2

1

Avoid testing html element presence for something like this. As you're using UI Bootstrap, you should inject the $modal service into your tests and spy on its open method. Then test your code's calls to it. This prevents DOM pollution during your tests.

This pattern should get you started:

var $modal;

beforeEach(inject(function($injector) {
    $modal = $injector.get('$modal');
}));

beforeEach(function() {
    spyOn($modal, 'open');
    // or, to mock/fake a modal object so you can test close/dismiss handlers
    // spyOn($modal, 'open').and.returnValue(mockModal);
    // see: http://stackoverflow.com/a/21370703/2943490
});

describe('show', function() {
    it('should initially not show the modal', function() {
        expect($modal.open).not.toHaveBeenCalled();
    });

    it('should show the upload modal', function() {
        upload.show();
        $rootScope.$digest();

        expect($modal.open).toHaveBeenCalledWith({
            // your modal options
        });
    });
});
user2943490
  • 6,900
  • 2
  • 22
  • 38
  • Thanks! A good approach, definitely. I hadn't thought about spying on the modal service itself, but that makes perfect sense. I'll switch to this method. Out of curiosity, do you have any idea why I was getting the results I was? Is there something that isn't clearing between tests? – Octothorpe Dec 11 '14 at 17:44
  • @Octothorpe, your first observation was correct: "All I can determine is that the html is all getting thrown into the same space, and is compounding after each test." You can half get around this by searching the DOM for a `.modal` in an afterEach and removing it, but you won't have to trouble yourself with this by spying on `$modal.open`. Also note that `$modal` keeps an internal register of opened modals, so simply removing them from the DOM is not truly cleaning things up. – user2943490 Dec 11 '14 at 22:41
  • Ok cool, good to know. I still have a lot to learn about what goes on under the hood with a lot of this. Thanks for the confirmation! – Octothorpe Dec 12 '14 at 16:58
0

Right now you probably put the code to set up your test at the beginning of your file. Try to put it in a beforeEach statement instead.

ngstschr
  • 2,119
  • 2
  • 22
  • 38
  • Just added the full code for the unit test. Let me know if this might help clarify anything. I am not 100% sure what you mean. – Octothorpe Dec 10 '14 at 22:06