27

I could use some help to find a solution for my problem. I need to mock some data to my angular2 application when it makes a request to an api, I need to do something like:

$httpBackend.when('GET', '/userbookings/').respond(my json file data);

The problem is that all I can find on google, using the $httpBackend which is used for angularJS (angular 1).

Does any know how I can get this to work in my E2E test (The application is an angular2 applciation)? I'm trying to do this with both protractor or nightwatch (Have tried both frameworks)

Spec test:

describe('Protractor Mocking bookings for angular2 site', function() {

var ngMockE2E = require('ng-mock-e2e');

var $httpBackend = ngMockE2E.$httpBackend;

beforeEach(function() {
    ngMockE2E.addMockModule();
    ngMockE2E.addAsDependencyForModule('myApp');
    ngMockE2E.embedScript('/bower_components/angular-mocks/angular-mocks.js');
});


afterEach(function() {
    ngMockE2E.clearMockModules();
});

it('Inject mock data of bookings', function() {

    var EC = protractor.ExpectedConditions;
    var global = require('../bin/globals.js');

    // Bookings data in a json file which should be send as the response
    var mockData = require('../testData.json');

    browser.ignoreSynchronization = false;

    $httpBackend.when('GET', '/userbookings').respond(mockData);

    browser.get(global.so.enLoggedIn);

});

});

This test wont work because it's using some angular1 way. Have showed it, so you can see how my test looks like.

Hope someone can help me out here, cause its really hard to find some working with angular2.

Mandersen
  • 785
  • 3
  • 13
  • 22
  • I would recommend this package https://github.com/atecarlos/protractor-http-mock. – finspin Apr 01 '16 at 16:41
  • Have you tried it with angular 2?. Have already tried it and looked at it.. The description of how it works is hard to understand. Maybe it's just me. – Mandersen Apr 01 '16 at 18:02
  • Is what you are searching for something described here? It's not really inside a test environment but would be no problem to port over. http://www.sitepoint.com/angular-2-mockbackend/ – zewa666 Apr 09 '16 at 16:41
  • I take a look when I'm back at work.. looks interesting - Thanks so far! – Mandersen Apr 09 '16 at 18:30
  • Doesn't really help me :(, I need some kind of a lib I can get via npm. – Mandersen Apr 12 '16 at 08:08
  • well the library itself is part of Angular2 which is installed via NPM – zewa666 Apr 12 '16 at 14:06
  • oh ok I see you want that used for a real E2E test vs Unit test ... sry my mistake. – zewa666 Apr 12 '16 at 14:20

5 Answers5

26

Protractor does not yet support adding mock modules for Angular 2 applications:

// TODO: support mock modules in Angular2. For now, error if someone
// has tried to use one.
if (self.mockModules_.length > 1) {
  deferred.reject('Trying to load mock modules on an Angular2 app ' +
      'is not yet supported.');
}

And, I've also created a github issue for the TODO to draw attention:

This, by the way, also means that protractor-http-mock is not gonna work since it relies on addMockModule internally. I've personally tried protractor-http-mock on a sample Angular2 application, got:

Failed: Trying to load mock modules on an Angular2 app is not yet supported.

Same is true for the http-backend-proxy and httpbackend packages.


I guess, while the issue is not yet fixed, you should consider firing up a proxy that would act as a sort of a "external mock" to your API backend, haven't done that personally, see more at:

Ashley
  • 2,074
  • 1
  • 30
  • 58
alecxe
  • 414,977
  • 106
  • 935
  • 1,083
  • Great answer, do you know if it has been implemented ? I m always looking for how to mock backend with e2e testing :-/ – mfrachet Jul 01 '16 at 06:23
  • @Skahrz thanks, unfortunately, it looks like it is not yet supported. – alecxe Jul 01 '16 at 12:58
  • I can't find any other resources but this question on SO. I am facing the same issue, and I am wondering if there still is no support for mock backends as of Angular 2.0.2 and Protractor 4.0.9? – CharlyDelta Oct 08 '16 at 23:31
3

Ended up using json-server as there is still no support of addMockModule for Angular 2

nastyklad
  • 321
  • 1
  • 7
3

I found a solution to this that is relatively painless and so far works great, and doesn't require you changing all the references to your existing imports.

There are several steps depending on what you are trying to accomplish. I was working on e2e tests, so this will outline that solution.

First update your angular.json with configs that are specific to your test environment, (right above "serve") mine is:

"serve-e2e": {
    builder: '@angular-devkit/build-angular:dev-server',
    options: {
        browserTarget: '{APP_NAME}:build'
    },
    configurations: {
        test: {
            browserTarget: '{APP_NAME}:build:test'
        }
    }
};

Then, update your existing e2e config by updating the devServerTarget with your new config:

"devServerTarget": "{APP_NAME}:serve-e2e:test"

Next I created a new set of environment specific files called mock-service-mapping, so in my environment folder I now have:

mock-service-mapping.ts
mock-service-mapping.test.ts

In these files, I store the mapping to my real and mock services:

import { RealDataService } from '../app/lib/services/real-data.service';

export const mockServiceMapping = {
     dataServiceClass: RealDataService
};

Now we need to make them environment specific. Update your angular.json to setup the proper mappings for your different environments:

"test": {
    fileReplacements: [
        {
            replace: 'src/environments/environment.ts',
            with: 'src/environments/environment.test.ts'
        },
        {
            replace: 'src/environments/mock-service-mapping.ts',
            with: 'src/environments/mock-service-mapping.test.ts'
        }
    ]
};

And the last piece of magic. In your module declarations, setup your providers to pull the class from your new mock environment files.

{ provide: DataService, useClass: mockServiceMapping.dataServiceClass }

And voila, mock services, no libraries, no mess, no extra compiled code, and fairly straightforward!

Gabriel Doty
  • 1,326
  • 1
  • 9
  • 6
  • Thanks so much for this! It took me a while to understand all the parts, so I've written it up into an example app, but with a slight reworking (used as a case for a bug in Protractor): see https://github.com/henrahmagix/protractor-onpageload-bug/tree/9ca37af6395e85c9ed4ae2182c20b9222e700066#solution – Henry Blyth Apr 25 '19 at 10:02
1

As there is no support for mocked modules in angular 2, i made a small protractor plugin that allows mock ajax request. You can find it here: https://github.com/krisboit/protractor-xmlhttprequest-mock

There is no documentation yet, but you can find sample tests. I hope it helps you.

  • Hey, I wasn't able to run this example. However quick fix which helped me was to replace `browser.executeScript` with `browser.driver.executeScript` in `index.js` – Andurit Apr 28 '17 at 07:12
-1

Personnally, I used the ng-apimock plugin to mock all network calls to the backend with a proxy.

It works really well and is simple to configure. Just follow the configuration for Angular application here

Arnaud P
  • 9,645
  • 3
  • 48
  • 57
glucas
  • 239
  • 1
  • 7