简体   繁体   中英

AngularJS unit testing dependencies

I need to make unit tests in AngularJS project, I've never done it before and I got a problems in first step.

Packages:

"jasmine-core": "^2.8.0",
"karma": "^1.7.1",
"karma-chrome-launcher": "^2.2.0",
"karma-jasmine": "^1.1.0"

Controller (as syntax):

angular.module('app').controller('LoginController', ['models.store', function(MODELS) {
    var vm = this;
    vm.account = new MODELS.Account('', '');
}]);

So I need to write a test for this controller property - account

Test:

describe('LoginTest', function() {
    var MODELS;

    beforeEach(module('app'));

    beforeEach(inject(function($injector) {
        inject(function() {
            MODELS = jasmine.createSpy('models.store');
        });
    }));

    beforeEach(inject(function($controller) {
        scope = $controller('LoginController', {'models.store': MODELS});
    }));

    it('Account model values should be empty', function() {
        expect(scope.account.login).toBe('');
    });
});

And I get "TypeError: MODELS.Account is not a constructor"

Injecting factory code:

angular.module('app.models').factory('models.store', function() {
    return {
        Account: function() {
            this.login = login || '';
            this.password = password || '';
        }
    }
});

What do I do wrong? What should I do to make the test correct?

The very first iteration can look like that:

 angular.module('app', ['app.models']) angular.module('app').controller('LoginController', ['store', function(MODELS) { var vm = this; vm.account = new MODELS.Account('', ''); }]); angular.module('app.models', []) angular.module('app.models').factory('store', function() { return { Account: function(login, password) { this.login = login || ''; this.password = password || ''; } } }); describe('LoginTest', function() { beforeEach(module('app')); beforeEach(inject(function($controller, store) { scope = $controller('LoginController', { 'store': store }); })); it('Account model values should be empty', function() { expect(scope.account.login).toBe(''); }); }); 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine-html.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/boot.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-mocks.js"></script> 

Another approach can be described as

 angular.module('app', ['app.models']) angular.module('app').controller('LoginController', ['store', function(MODELS) { var vm = this; vm.account = new MODELS.Account('', ''); }]); angular.module('app.models', []) describe('LoginTest', function() { var stubStore beforeEach(module('app')); beforeEach(function() { stubStore = { Account: jasmine.createSpy() } }) beforeEach(function() { stubStore.Account }) beforeEach(inject(function($controller) { scope = $controller('LoginController', { 'store': stubStore }); })); it('Account model values should be empty', function() { expect(stubStore.Account).toHaveBeenCalledWith('', '') }); }); 
 <link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/jasmine-html.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.8.0/boot.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-mocks.js"></script> 

Thank you all!

The only successful way were:

beforeEach(function() {
    var scope, MODELS;

    beforeEach(function() {
        module('app');
    });

    beforeEach(inject(function($injector) {
        MODELS = $injector.get('models.store');
    }));

    beforeEach(inject(function($controller) {
        scope = $controller('LoginController', {});
    }));

    it('Expect Account model Login is empty', function () {
        expect(scope.account.login).toBe('');
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM