将Angularjs应用程序中的对象暴露给量角器测试

将Angularjs应用程序中的对象暴露给量角器测试,angularjs,unit-testing,protractor,e2e-testing,Angularjs,Unit Testing,Protractor,E2e Testing,我正在使用量角器为基于AngularJS的应用程序编写端到端测试。有些情况需要使用mock进行测试,例如,网络连接问题。如果对服务器的AJAX请求失败,用户必须看到警告消息 我的模拟在应用程序中注册为服务。我希望它们能够被测试访问,以编写如下内容: var proxy; beforeEach(function() { proxy = getProxyMock(); }); it("When network is OK, request succeeds", function(done) {

我正在使用量角器为基于AngularJS的应用程序编写端到端测试。有些情况需要使用mock进行测试,例如,网络连接问题。如果对服务器的AJAX请求失败,用户必须看到警告消息

我的模拟在应用程序中注册为服务。我希望它们能够被测试访问,以编写如下内容:

var proxy;
beforeEach(function() { proxy = getProxyMock(); });

it("When network is OK, request succeeds", function(done) {
    proxy.networkAvailable = true;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(0);
        done();
    });
});

it("When network is faulty, message is displayed", function(done) {
    proxy.networkAvailable = false;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(1);
        done();
    });
});
angular.module('myModule', [])
       .service('proxy', NetworkProxy)
       .run(function(proxy) {
           window.MY_SERVICES = {
               proxy: proxy,
           };
       });
it("Testing the script", function(done) {
    browser.executeScript(function() {
        window.MY_SERVICES.proxy.networkAvailable = false;
    });

    element(by.id('loginButton')).click().then(function() {
        expect(element.all(by.id('error')).count()).toEqual(1);
        done();
    });
});

如何实现
getProxyMock
函数将对象从应用程序传递到测试?我可以在应用程序的
窗口
对象中存储代理,但仍然不知道如何访问它。

在阅读并更好地理解了测试过程后,这就不可能了。测试在NodeJS中执行,浏览器-Javascript对象实例中的前端代码无法在两个不同的进程之间真正共享

不过,有一个变通方法:您可以在浏览器中执行脚本

首先,您的前端代码必须提供某种服务定位器,如下所示:

var proxy;
beforeEach(function() { proxy = getProxyMock(); });

it("When network is OK, request succeeds", function(done) {
    proxy.networkAvailable = true;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(0);
        done();
    });
});

it("When network is faulty, message is displayed", function(done) {
    proxy.networkAvailable = false;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(1);
        done();
    });
});
angular.module('myModule', [])
       .service('proxy', NetworkProxy)
       .run(function(proxy) {
           window.MY_SERVICES = {
               proxy: proxy,
           };
       });
it("Testing the script", function(done) {
    browser.executeScript(function() {
        window.MY_SERVICES.proxy.networkAvailable = false;
    });

    element(by.id('loginButton')).click().then(function() {
        expect(element.all(by.id('error')).count()).toEqual(1);
        done();
    });
});
然后,测试是这样进行的:

var proxy;
beforeEach(function() { proxy = getProxyMock(); });

it("When network is OK, request succeeds", function(done) {
    proxy.networkAvailable = true;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(0);
        done();
    });
});

it("When network is faulty, message is displayed", function(done) {
    proxy.networkAvailable = false;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(1);
        done();
    });
});
angular.module('myModule', [])
       .service('proxy', NetworkProxy)
       .run(function(proxy) {
           window.MY_SERVICES = {
               proxy: proxy,
           };
       });
it("Testing the script", function(done) {
    browser.executeScript(function() {
        window.MY_SERVICES.proxy.networkAvailable = false;
    });

    element(by.id('loginButton')).click().then(function() {
        expect(element.all(by.id('error')).count()).toEqual(1);
        done();
    });
});

请注意,当您使用
executeScript
时,函数将被序列化以发送到浏览器执行。这就需要记住一些限制:如果脚本函数返回一个值,它就是浏览器中原始对象的克隆。更新返回值将而不是修改原始值!出于同样的原因,您不能在函数中使用闭包。

在阅读并更好地理解了测试过程之后,这就不可能了。测试在NodeJS中执行,浏览器-Javascript对象实例中的前端代码无法在两个不同的进程之间真正共享

不过,有一个变通方法:您可以在浏览器中执行脚本

首先,您的前端代码必须提供某种服务定位器,如下所示:

var proxy;
beforeEach(function() { proxy = getProxyMock(); });

it("When network is OK, request succeeds", function(done) {
    proxy.networkAvailable = true;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(0);
        done();
    });
});

it("When network is faulty, message is displayed", function(done) {
    proxy.networkAvailable = false;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(1);
        done();
    });
});
angular.module('myModule', [])
       .service('proxy', NetworkProxy)
       .run(function(proxy) {
           window.MY_SERVICES = {
               proxy: proxy,
           };
       });
it("Testing the script", function(done) {
    browser.executeScript(function() {
        window.MY_SERVICES.proxy.networkAvailable = false;
    });

    element(by.id('loginButton')).click().then(function() {
        expect(element.all(by.id('error')).count()).toEqual(1);
        done();
    });
});
然后,测试是这样进行的:

var proxy;
beforeEach(function() { proxy = getProxyMock(); });

it("When network is OK, request succeeds", function(done) {
    proxy.networkAvailable = true;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(0);
        done();
    });
});

it("When network is faulty, message is displayed", function(done) {
    proxy.networkAvailable = false;

    element(by.id('loginButton')).click().then(function() {
        expect(element(by.id('error')).count()).toEqual(1);
        done();
    });
});
angular.module('myModule', [])
       .service('proxy', NetworkProxy)
       .run(function(proxy) {
           window.MY_SERVICES = {
               proxy: proxy,
           };
       });
it("Testing the script", function(done) {
    browser.executeScript(function() {
        window.MY_SERVICES.proxy.networkAvailable = false;
    });

    element(by.id('loginButton')).click().then(function() {
        expect(element.all(by.id('error')).count()).toEqual(1);
        done();
    });
});
请注意,当您使用
executeScript
时,函数将被序列化以发送到浏览器执行。这就需要记住一些限制:如果脚本函数返回一个值,它就是浏览器中原始对象的克隆。更新返回值将而不是修改原始值!出于同样的原因,您不能在函数中使用闭包