Prasad
Prasad

Reputation: 1600

How can I Unit Test Rest Angular Service and Controller?

Rest-angular for Api Calling .

My Aim to Write a Unit test Case by calling Controller and Test all the Scope are assigned,the Code blocks of with REST API Response But not MOCK RESPONSE.

Rest Angular Service :-

(function () {

    angular.module('movieApp').service('movieApiService', callMoviesApi);

    function callMoviesApi(Restangular) {
        this.getMyMovie= function (Id) {
            return  Restangular.one('movies/' + movieId).get().then(function(result){
                return result.plain();
            });
        };

        this.getMoviesList = function () {
            return Restangular.all('movies').getList().then(function(result){
              return result.plain();
            });
        };
    }

}());

Where I am Injecting this Service to Controller as a Dependency Controller Code Follows :-

angular.module('movieApp').controller('MoviesController', ['$scope','movieApiService', function ($scope, MovieService) {

    $scope.movie = $stateParams.movieId;

    MovieService.getMovieDetails($scope.movie).then(function (result) {
        $scope.movieDetails = result;
        $scope.movieId = result._id;
        $scope.movieName = result.displayName;
    });
}
]);

I did tried to Write a Unit test for the Above Controller not Going good :-(

Test Code Follows:-

'use strict';

(function() {
    describe('MoviesController', function() {
        //Initialize global variables
        var scope,stateParams={},
            MoviesController;

        // Load the main application module
        beforeEach(module('movieApp'));

        beforeEach(inject(function($controller, $rootScope,$stateParams) {
            scope = $rootScope.$new();

            stateParams.movieId='Baahubali';

            HomeController = $controller('MoviesController', {
                $scope: scope,
                $stateParams:stateParams
            });
        }));

    it('Should call movieApi and Assign Scopes', function() {
          var Api="http://testsite.com/moives/thor";
          var myScope=$httpBackend.expectGET(Api).passthrough(); 
           expect(scope.movie).toBeDefined();
            console.log('****'+scope.movie.displayName);

            });
        });
    })();

Error is Raising :-

Error: Unexpected request: GET http://testsite.com/movies/undefined
        Expected GET http://testsite.com/movies/undefined? 
            at $httpBackend (C:/wrokingdir2015/public/lib/angular-mocks/angular-mocks.js:1245)
            at sendReq (C:/wrokingdir2015/public/lib/angular-mocks/public/lib/angular/angular.js:9695)

Could Any One help me to Write a Unit test case Which can Initialize controller and Assing Scopes like in real controller for testing .

Honestly iam New Guy for Unit testing .

Upvotes: 0

Views: 1430

Answers (3)

chaaya
chaaya

Reputation: 26

First of all i would use Restangulars one method as it supposed to be used. Read more about it here: https://github.com/mgonto/restangular#creating-main-restangular-object

Restangular.one('movies', movieId);

In my service test i would do something like this to test that the correct endpoint has been called.

it('should call /movies/{movieId}', function() {
        var spy = sinon.spy(Restangular, 'one');
        var movieId = 1;
        movieApiService.getMyMovie(movieId);
        expect(spy).to.have.been.calledWith('movies', movieId);
});

Then I would make a sinon stub to mock the reponse from the service in another test for the controller.

it('should set my movies variabel after calling movie service', function() {
        var mockResponse = [
                    {
                      id: 1,
                      title: 'Titanic'
                    },
                    {
                      id: 2,
                      title: 'American History X'
                    }

        ];
        sinon.stub(movieApiService, 'getMyMovie')
             .returns(
                 $q.when(
                 [
                    {
                      id: 1,
                      title: 'Titanic'
                    },
                    {
                      id: 2,
                      title: 'American History X'
                    }

                 ]
                 );
             );
             expect($scope.movieList).to.equal(mockResponse);

});

And another test for checking that the controller catch function is called.

it('should call error handling if service rejects promise', function() {
        sinon.stub(movieApiService, 'getMyMovie')
             .returns(
                 $q.reject('an error occured when fetching movie'); 
             );
});

Upvotes: 1

aurelius
aurelius

Reputation: 4076

I suggest Selenium with Cucumber for having the scenarios that you test in a nice and readable format

but for testing only a REST api you just need an implementation of javax.ws.rs.client.Client, I use org.glassfish.jersey.client.JerseyClient.

private final Client client = ClientBuilder.newClient();

e.g.

    @When("^I want to retrieve all cells for the report with id \"([^\"]*)\".$")
    public void accessCellReport(String id) {
        response = client.target(URL).path(PathConstants.PATH_ID)
                         .resolveTemplate(PathConstants.PARAM_ID, reportId).request(MediaType.APPLICATION_JSON).get();

        RestAssertions.assertResponseOk(response);
    }

Upvotes: 1

I suggest using Selenium:

http://www.seleniumhq.org/.

Easy to write unit tests and can be automatized with jenkins build.

Upvotes: 0

Related Questions