mercredi 3 février 2016

AngularJS Testing and $http

So Im trying to figure out how to write unit tests for my angular controller. I am using karma as my runner. I was able to write 1 successful test but every time I try to write another test it yells at me about unexpected calls and such.

Here is my controller im trying to test.

(function (angular) {
'use strict';
var ngModule = angular.module('myApp.dashboardCtrl', []);
ngModule.controller('dashboardCtrl', function ($scope, $http) {

    //"Global Variables"
    var vm = this;
    vm.success = false;
    vm.repos = [];

    //"Global Functions"
    vm.addRepository = addRepository;
    vm.listRepos = listRepos;

    //Anything that needs to be instantiated on page load goes in the init
    function init() {
        listRepos();
    }
    init();

    // Add a repository
    function addRepository(repoUrl) {
        $http.post("/api/repo/" + encodeURIComponent(repoUrl)).then(function (){
            vm.success = true;
            vm.addedRepo = vm.repoUrl;
            vm.repoUrl = '';
            listRepos();
        });
    }
    //Lists all repos
    function listRepos() {
        $http.get('/api/repo').then( function (response){
            vm.repos = response.data;

        });
    }
});
}(window.angular));

So I have a test written for listRepos(). It goes as follows

describe('dashboardCtrl', function() {
var scope, httpBackend, createController;
// Set up the module
beforeEach(module('myApp'));

beforeEach(inject(function($rootScope, $httpBackend, $controller) {
    httpBackend = $httpBackend;
    scope = $rootScope.$new();
    createController = function() {
        return $controller('dashboardCtrl', {
            '$scope': scope
        });
    };
}));

afterEach(function() {
    httpBackend.verifyNoOutstandingExpectation();
    httpBackend.verifyNoOutstandingRequest();
});

it('should call listRepos and return all repos from the database', function() {
    var controller = createController();
    var expectedResponse = [{id: 12345, url: "http://ift.tt/1P6vPAp"}];

    httpBackend.expect('GET', '/api/repo')
        .respond(expectedResponse);
    httpBackend.flush();

    scope.$apply(function() {
        scope.listRepos;
    });

    expect(controller.repos).toEqual(expectedResponse);
});

This works and the test passes. Now my problem is I want to write another test to test the other function that calls a new api endpoint.

This is the test im trying to write for addRepository.

 it('should addRepository to the database', function() {
        var controller = createController();
        var givenURL = "http://ift.tt/1PzUdf9";

        httpBackend.expect('POST', '/api/repo/' + encodeURIComponent(givenURL)).respond('success');
        httpBackend.flush();

        scope.$apply(function() {
            scope.addRepository(givenURL);
        });

        expect(controller.success).toBe(true);
        expect(controller.listRepos).toHaveBeenCalled();
    });

The error I get when I add this test to the spec is:

Error: Unexpected request: GET /api/repo
Expected POST /api/repo/https%3A%2F%2Fgithub.com%2Fmyuser%2FmyURLtoMyRepo.git
    at $httpBackend 
Error: [$rootScope:inprog] $digest already in progress
http://ift.tt/1P6vNsl

The example I am working with is this one here

Any suggestions or tips is greatly appreciated!

Aucun commentaire:

Enregistrer un commentaire