Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to verify $httpBackend mock expectations in a Protractor test?

I'm developing a frontend for a REST API. I'm using Protractor for end-to-end tests with the API mocked out because I want to be able to test the frontend in isolation.

Here's a simple test I got:

describe('partner', function () {
    it('should list partners', function () {
        var page = new PartnerListPage();
        var httpBackendMock = function () {
            angular.module('httpBackendMock', ['ngMockE2E'])
                .run(function ($httpBackend) {
                    $httpBackend.whenGET('/api/partners').respond(200, {
                        _embedded: {
                            partners: [
                                {
                                    firstName: 'Elnur',
                                    lastName: 'Abdurrakhimov'
                                }
                            ]
                        }
                    });
                    $httpBackend.whenGET(/.*/).passThrough();
                });
        };
        browser.addMockModule('httpBackendMock', httpBackendMock);

        page.open();
        expect(page.isOpen()).toBeTruthy();
        expect(page.getPartner(0).firstName).toBe('Elnur');
        expect(page.getPartner(0).lastName).toBe('Abdurrakhimov');
    });
});

What it does is basically create a mock of the backend so that it returns something I want it to.

It's all fine and dandy except for one thing. I want to be able to call the following methods at the end of the test:

$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();

The reason I want to do that is to verify that the mock is getting the expected requests. It doesn't make much sense for the test I've provided, but let's say I want to verify that when I submit some form, a particular POST request with particular data is being executed. I want to do the verification on the backend mock itself so that my test is isolated from outputting the result of the response of that POST request because that will be tested in another test.

How do I get access to the same $httpBackend instance that's being used in the httpBackendMock I've added to browser?

As far as I understand, Protractor and the app itself run in separate processes. Therefore I can't get access to $httpBackend directly the same way I can in a unit test.

like image 559
Elnur Abdurrakhimov Avatar asked Oct 21 '22 06:10

Elnur Abdurrakhimov


1 Answers

Your application is execute in the browser and protractor in a separate process. So you are right you can't access directly the browser context.

Fortunately, protractor provide a mechanism to execute javascript in the browser. I guess you could use this mechanism to access the $httpBackendMock.

browser.executeAsyncScript(function() {
  var $httpBackend = angular.injector(['httpBackendMock']).get('$httpBackend');
  $httpBackend.verifyNoOutstandingExpectation();
  $httpBackend.verifyNoOutstandingRequest();
});

NB: Code adapted from this answer.


Another option could be to expose a "check URL"

$httpBackend.whenGET('/api/check').respond(function() {
    $httpBackend.verifyNoOutstandingExpectation();
    $httpBackend.verifyNoOutstandingRequest();
    return [200];
});

and use it in your test:

browser.get('/api/check');
like image 54
gontard Avatar answered Oct 22 '22 23:10

gontard