Используйте Mock HTTP с транспортиром и жасмином

Как я могу использовать Mock HTTP с Jasmine и Protractor?

В моем test.spec.js я объявил макет, но этот макет не работает. У меня нет ошибок. Мой API всегда отвечает, а не издеваться.

Я никогда не вижу 'mockModule!' в моей консоли. Моя функция никогда не выполняется:

browser.addMockModule('modName', function() {

    browser.executeScript(function() {console.log('mockModule!')});

    angular.module('modName', []).value('foo', 'bar').run(function ($httpBackend) {
    $httpBackend.whenPOST('http://api.webapp.net/app_dev.php/module/search?direction=asc&page=1').respond('repsond');

    browser.executeScript(function() {console.log('enter mockModule!')});
    });
});

В моем app.js у меня нет "ngMock".

Я добавил это в свой index.html:

node_modules/angular-mocks/angular-mocks.js

Я запускаю тест из командной строки с помощью 'gulp protractor-local':

gulp.task('protractor-local', shell.task([
        'protractor protractor.conf.js --baseUrl="http://mywebapp.local.net"'
]));

Все тесты в порядке, но не макет.

test.spec.js

var loginPO = new(require('./models/login.model.js'))();

describe("hello", function() {

    it("I click on the button-search button", function() {

        loginPO.wait(10);

        //browser.ignoreSynchronization = false;

        browser.addMockModule('modName', function() {

            browser.executeScript(function() {console.log('mockModule!')});

            angular.module('modName', []).value('foo', 'bar').run(function ($httpBackend) {
                $httpBackend.whenPOST('http://api.webapp.net/app_dev.php/module/search?direction=asc&page=1').respond('repsond');

                browser.executeScript(function() {console.log('enter mockModule!')});
            });
        });

        //browser.getRegisteredMockModules();

        loginPO.clickButtonSearchButton();
        loginPO.wait(10);
    });

    it("I am on the home page", function() {
        loginPO.visit('#/');
    });

    ...

});

Модели /login.model.js

'use strict';

var _ = require('lodash');

var LoginPageObject = function() {

    var signInButton = element(by.id('signIn'));

    _.mixin(this, require('./common/base.js').Base);

    this.path = '#/';

    this.clickButtonSearchButton = function() {
        return browser.driver.findElement(by.id('button-search')).click();
    };

    ...

};

module.exports = LoginPageObject;

общие / base.js

function visit(path, params) {
    return browser.get(this.path + (params || ''));
}

function wait(params) {
    params = params * 1000;
    return browser.sleep(params);
}
...

exports.Base = {
    visit: visit,
    wait: wait,
    ...
};

protractor.config.js

exports.config = {
  directConnect: true,

  seleniumServerJar: 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.48.2.jar',

  specs: [
    'jasmine/*.spec.js'
  ],

  getPageTimeout: 30000,

  capabilities: {
    'browserName': 'chrome',
    version: '',
    platform: 'ANY'
  },

  framework: 'jasmine2'

};

** karma.conf.js **

// Karma configuration

module.exports = function(config) {

    var configuration = {

        basePath: './',

        frameworks: [
            'jasmine-jquery',
            'jasmine',
            'jasmine-matchers'
        ],

        files: [
            ...
            'assets/libs/angularjs/angular.min.js',
            'node_modules/angular-mocks/angular-mocks.js',
            ...
            'assets/libs/angularjs/sweetalert.min.js',
            'assets/libs/angularjs/ui-bootstrap-tpls.min.js',
            'app/app.js',
            'app/*/*.js',
            'app/*/*/*.js',
            'app/*/*/*/*.js',
            {
                pattern: 'app/*/*/*/*/*.json',
                included: false
            }
        ],

        exclude: [],

        preprocessors: {
            'app/**/!(*.test).js': ['coverage']
        },

        coverageReporter: {
            type: 'text',
            dir: 'coverage/'
        },

        reporters: ['spec'],

        port: 8080,

        colors: true,

        logLevel: config.LOG_INFO,

        autoWatch: false,

        browsers: ['PhantomJS'],

        singleRun: true,

        customLaunchers: {
            'PhantomJS_custom': {
                base: 'PhantomJS',
                    options: {
                        windowName: 'my-window',
                        settings: {
                        webSecurityEnabled: false
                    }
                },
                flags: ['--load-images=true'],
                debug: true
            }
        },

        phantomjsLauncher: {
            exitOnResourceError: true
        }
    };

    config.set(configuration);
};

package.json

{
  "name": "webapp",
  "version": "1.0.0",
  "description": "webapp",
  "dependencies": {
    "angular-mocks": "^1.4.5",
    "chromedriver": "^2.19.0",
    "gulp-protractor": "^1.0.0",
    "gulp-shell": "^0.5.0",
    ...
    "protractor": "^2.5.1",
    "selenium-server": "^2.48.2",
    "selenium-standalone": "^4.7.0",
    "selenium-webdriver": "^2.48.0",
  }
}

2 ответа

Решение

У меня тоже была такая же проблема, и я решил ее, создав модуль-обертку со всеми макетами

  angular.module('mockBackend', ['myAppModule', 'ngMockE2E']).run(function ($httpBackend) {
    $httpBackend.when('GET', /user/).respond(200, {login: 'user_test'});
  });

И измените директиву data-ng-app в индексном файле на модуль mockBackend

<html data-ng-app='mockBackend'>

Вы можете настроить задачу gulp / grunt на включение этого модуля и изменить data-ng-app перед запуском ваших тестов.

В этой ссылке вы можете увидеть полный пример: http://blog.xebia.com/angularjs-e2e-testing-using-ngmocke2e/

Первое, что вы смешиваете тестирование E2E и модульное тестирование жасмина. Для тестирования E2E используется транспортир.

Также убедитесь, что вы включили путь к тестовому файлу в конфигурацию karma для модульного тестирования с жасмином.

Удостовериться Selenium webdriver-manager до даты

например

Фрагмент HTML для страницы входа.

<div class="form-group" 
             ng-class=" {'has-error' :!loginForm.userEmail.$pristine && loginForm.userEmail.$invalid}" >
            <label for="email">Enter Email</label>
            <input  type="email" name="userEmail"   class="form-control" required  placeholder="Enter Email" ng-model="objUser.userEmail">        
            <div ng-show="loginForm.userEmail.$touched || loginForm.$submitted">
                <span ng-show="loginForm.userEmail.$error.required">Please enter valid email</span>
                <span ng-show="loginForm.userEmail.$error.email">Please enter valid email</span>
            </div>
        </div>

Транспортир JS для этого HTML

describe("check user creation form integration", function() {

    var ptor,userEmail,userPassword;
    beforeEach(function(){
        ptor = protractor.ExpectedConditions;
        userEmail       = element(by.model("objUser.userEmail"));
    });

    it("\n\n1 . check login functionality",function(){

        browser.get("/#/");
        userEmail.sendKeys("*^*");
        expect(userEmail.getAttribute("class")).toContain('ng-invalid');
         userEmail.clear();
        browser.sleep(2000);
        userEmail.sendKeys("HJJHJH");
        expect(userEmail.getAttribute("class")).toContain('ng-valid');
    })
});

Конфигурация транспортира

добавить следующую строку

exports.config = {
  baseUrl: 'http://localhost:3000/'
};

порт будет изменен согласно вашей конфигурации.

Другие вопросы по тегам