使用Mock HTTP与量角器和Jasmine

时间:2015-11-24 12:58:08

标签: javascript angularjs jasmine protractor angularjs-e2e

如何在Jasmine和Protractor中使用Mock HTTP?

在我的 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 个答案:

答案 0 :(得分:1)

我也有同样的问题,我解决了它创建一个包含所有模拟的包装模块

  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/

答案 1 :(得分:0)

首先,您要混合E2E测试和茉莉花单元测试。 使用量角器进行E2E测试。

另外,请确保已在karma配置中包含测试文件路径以进行茉莉花单元测试。

确保Selenium webdriver-manager更新

e.g。

登录页面的摘录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>

这个html的量角器js

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/'
};

端口将根据您的配置进行更改。