如何在Protractor测试中验证$ httpBackend模拟期望值?

时间:2014-06-25 22:00:01

标签: angularjs protractor

我正在开发REST API的前端。我使用Protractor进行端到端测试,并且模拟了API,因为我希望能够单独测试前端。

这是一个简单的测试:

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

它的作用基本上是创建一个后端的模拟,以便它返回我想要的东西。

除了一件事,它一切都很美好。我希望能够在测试结束时调用以下方法:

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

我想这样做的原因是验证模拟是否获得了预期的请求。它对我提供的测试没有多大意义,但是我想说我想验证当我提交某个表单时,特定数据的特定POST请求正在进行中执行。我想对后端模拟本身进行验证,以便我的测试与输出POST请求的响应结果隔离,因为它将在另一个测试中进行测试。

如何访问我$httpBackend添加到httpBackendMock的{​​{1}}实例中使用的browser个实例?

据我了解,Protractor和应用程序本身在不同的进程中运行。因此,我无法像在单元测试中那样直接访问$httpBackend

3 个答案:

答案 0 :(得分:3)

您的应用程序在一个单独的进程中在浏览器和量角器中执行。所以你是对的,你无法直接访问浏览器上下文。

幸运的是,量角器为execute javascript in the browser提供了一种机制。我想你可以使用这种机制来访问$httpBackendMock

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

注意:代码改编自this answer


另一种选择可能是公开"检查网址"

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

并在测试中使用它:

browser.get('/api/check');

答案 1 :(得分:0)

您应该尝试在量角器测试中避免使用httpBackend存根。它可以在以后更改您的测试数据,这比需要的更复杂。 Protractor有一个很好的替代mockHttp,那就是Protractor#addMockModule。您可以使用它来模拟单个模块以使其返回所需的结果。在调用Protractor#get()之前,需要添加此代码。如果它与现有服务具有相同的名称,它将在应用程序服务覆盖后加载。

您可以按如下方式使用它:

var dataUtilMockModule = function () {
     // Create a new module which depends on your data creation utilities
    var utilModule = angular.module('dataUtil', ['platform']);
    // Create a new service in the module that creates a new entity
    utilModule.service('EntityCreation', ['EntityDataService', '$q', function (EntityDataService, $q) {

        /**
         * Returns a promise which is resolved/rejected according to entity creation success
         * @returns {*}
         */
        this.createEntity = function (details,type) {
            // This is your business logic for creating entities
            var entity = EntityDataService.Entity(details).ofType(type);
            var promise = entity.save();
            return promise;
        };
    }]);
};

browser.addMockModule('dataUtil', dataUtilMockModule);

您可以将此运行作为测试之前设置的一部分,然后通过调用Protractor#clearMockModules()来清除模拟模块列表,为后续部分返回默认值,为下一次设置做好准备。

答案 2 :(得分:0)

我找到了比使用$httpBackend方式更好的解决方案。

由于您在Node.js上运行Protractor测试,因此使用一些Node.js包来模拟后端更有意义,而不是我在问题中提出的这个丑陋和hacky解决方案。

Hock对我很有用,因此我建议使用它或类似的东西。