简体   繁体   中英

Unit testing Angular with Breeze

I am trying to unit test angularjs with QUnit but get the error messages: $httpBackend.whenGET is not a function, $httpBackend.when is not a function. I have included angular mocks and angular breeze service ( http://www.breezejs.com/documentation/breeze-angular-service ) which uses the angular q library for promises and httpbackend instead of $.ajax for data transmission. I am still unable to mock any of the calls to the server. Some sample code:

var $httpBackend,
    injector;
    var SPAModule = angular.module("spa");
    injector = angular.injector(['ng', 'spa']);
    $httpBackend = injector.get("$httpBackend");
    SPAModule.config(function ($provide) {
        $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);
    });

test("WHEN the controller is called THEN it should be created with the correct data on the scope", function () { 'use strict';

// Given
$httpBackend.whenGET("/Breeze/Data/Jobs").respond({ data: jobData });
$httpBackend.whenGET("/Breeze/Data/Metadata").respond({});
var routeParams = { id: "b" },

// When
    controller = injector.get('$controller')(toriga.propertyController, {
        $scope: theScope,
        $window: windowMock,
        $location: locationMock,
        $routeParams: routeParams
    }),
    $rootScope = injector.get('$rootScope');
$httpBackend.flush();
$rootScope.$apply(); // forces results of promise to be executed

// Then
notEqual(controller, null, 'controller was created properly');
strictEqual(theScope.pageTitle, "Property", "pageTitle was set on the scope");
notEqual(theScope.job, null, "Job set on the scope");
ok(toastrMock.warning.notCalled, "No warning messages were displayed");
ok(toastrMock.error.notCalled, "No error messages were displayed");

});

This code used to work fine when I was not using breeze but now I have switched I can't seem to get it to work and the documentation is poor on how to get this working. Any help would be appreciated.

I can't tell all of the details of your tests. I can offer some comfort that it does work .. and pretty much as you'd expect.

Here is an extract from the test/specs/lookups.spec in the "Zza-Node-Mongo" sample ( it's in github ) in which I replay through the $httpBackend mock a (subset of) the server's response to a Breeze client request for "lookup" reference entities.

I'm using Jasmine instead of QUnit but I hope you get the picture.

// simplified for presentation here but materially sufficient
describe("when lookups service receives valid lookups data", function () {

    var $httpBackend, flush$q, lookups
    var lookupsUrlRe = /breeze\/zza\/Lookups\?/; // RegEx of the lookups endpoint

    beforeEach(module('app')); 

    beforeEach(inject(function(_$httpBackend_, $rootScope, _lookups_) {
        $httpBackend = _$httpBackend_;
        flush$q = function() { $rootScope.$apply(); };
        lookups = _lookups_;
    }));

    beforeEach(function () {
        $httpBackend.expectGET(lookupsUrlRe).respond(validLookupsResponse.data);
        lookups.ready(); // THIS TRIGGERS CALL TO FETCHLOOKUPS
        $httpBackend.flush();
    });

    it("doesn't bomb", function () {
        expect(true).toBe(true);
    });

    it("'ready()' invokes success callback", function () {
       var success = jasmine.createSpy('success');
        lookups.ready(success);
        flush$q();  // NOTE NEED TO FLUSH $Q IN THIS TEST
        expect(success).toHaveBeenCalled();
    })

    it("has OrderStatus.Pending", function () {
        expect(lookups.OrderStatus && lookups.OrderStatus.Pending).toBeDefined();
    });

    ... more tests ...

});

The "lookups" service ( app/services/lookups.js ) calls breeze to fetch lookups data from the server.

function fetchLookups() {
   return breeze.EntityQuery.from('Lookups')
       .using(manager).execute()
       .then(function () {
           logger.info("Lookups loaded from server.");
           extendService(manager)
       })
       .catch(function (error) {
           error = util.filterHttpError(error);
           logger.error(error.message, "lookups initialization failed");
           throw error; // so downstream fail handlers hear it too
       });
}

As you might imagine, this is a pretty deep integration test that starts with a service consumed by a ViewModel and goes all the way through the Breeze Angular Service through $http just about to the network boundary before being intercepted by $httpBackend .

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