Testing $resource services in AngularJS

前端 未结 2 611
一整个雨季
一整个雨季 2020-12-22 22:41

I am trying to begin writing unit tests for my angular application and hit a stopping block pretty quick as I am unsure of how exactly to mock my service in a testable way.<

相关标签:
2条回答
  • 2020-12-22 23:26

    zsong's answer greatly helped me understand this, but I would like to expand on how it works. In case it gets edited, I list the code again here:

    describe('User', function () {
        var mockUserResource, $httpBackend;
        beforeEach(angular.mock.module('myApp'));
    
        beforeEach(function () {
            angular.mock.inject(function ($injector) {
                $httpBackend = $injector.get('$httpBackend');
                mockUserResource = $injector.get('User');
            })
        });
    
        describe('getUser', function () {
            it('should call getUser with username', inject(function (User) {
                $httpBackend.expectGET('/api/index.php/users/test')
                    .respond([{
                    username: 'test'
                }]);
    
                var result = mockUserResource.getUser('test');
    
                $httpBackend.flush();
    
                expect(result[0].username).toEqual('test');
            }));
    
        });
    });
    

    What's going on here?

    1

    beforeEach(angular.mock.module('myApp'));
    

    We tell the Angular injector ($injector and angular.mock.inject) to inject things defined in the myApp module. You can think of it as defining a module dependency without a dependent module. Compare with how things defined in the myApp module can be injected in, say, a controller in a angular.module('myOtherApp', ['myApp']) module.

    2

    beforeEach(function () {
        angular.mock.inject(function ($injector) {
            $httpBackend = $injector.get('$httpBackend');
            mockUserResource = $injector.get('User');
        })
    });
    

    Before each spec, run the function ($injector) function with dependencies injected. In this case, the dependency ($injector) is resolved implicitly from the parameter name. A functionally equivalent variant of this snippet is

    beforeEach(function () {
        angular.mock.inject(['$httpBackend', 'User', function ($httpB, User) {
            $httpBackend = $httpB;
            mockUserResource = User;
        }]);
    });
    

    Here we have instead declared the dependencies explicitly, and are free to use any parameter names we wish.

    3

    it('should call getUser with username', inject(function (User) {
    

    Again, the test function is injected with the implicitly resolved User service as a parameter, though it isn't actually used.

    Notice that this time there is no wrapper function around the inject call. inject invokes the passed function immediately if a spec is currently running, but otherwise it returns a wrapper function (see the inject docs and source code), so we don't actually need the wrapper function. Thus, we could have written the beforeEach snippet above like this:

    beforeEach(angular.mock.inject(function ($injector) {
        $httpBackend = $injector.get('$httpBackend');
        mockUserResource = $injector.get('User');
    }));
    
    0 讨论(0)
  • 2020-12-22 23:43

    You can mock the requests made by ngResource like this:

    describe('User', function () {
        var mockUserResource, $httpBackend;
        beforeEach(angular.mock.module('myApp'));
    
        beforeEach(function () {
            angular.mock.inject(function ($injector) {
                $httpBackend = $injector.get('$httpBackend');
                mockUserResource = $injector.get('User');
            })
        });
    
        describe('getUser', function () {
            it('should call getUser with username', inject(function (User) {
                $httpBackend.expectGET('/api/index.php/users/test')
                    .respond([{
                    username: 'test'
                }]);
    
                var result = mockUserResource.getUser('test');
    
                $httpBackend.flush();
    
                expect(result[0].username).toEqual('test');
            }));
    
        });
    });
    

    Demo

    0 讨论(0)
提交回复
热议问题