2013-02-01 46 views
3

我想對e2e方案的指令做一些基本的測試。代碼工作正常 ,我可以將新元素呈現給瀏覽器。這裏是我使用的代碼。Angular.js e2e測試HTTP請求到外部服務

這裏的指令代碼。

'use strict'; 

var directives = angular.module('lelylan.directives', []) 

directives.directive('device', ['Device', function(Device) { 
    var definition = { 
    restrict: 'E', 
    replace: true, 
    templateUrl: 'js/templates/device.html', 
    scope: { id: '@' } 
    }; 

    definition.link = function postLink(scope, element, attrs) { 
    scope.$watch('id', function(value){ 
     var device = Device.get({ id: scope.id }, function() { 
     scope.device = device; 
     }); 
    }); 
    }; 

    return definition 
}]); 

這裏的設備服務代碼。

// Service Device 
'use strict'; 

angular.module('lelylan.services', ['ngResource']). 
    factory('Device', ['$resource', '$http', function($resource, $http) { 

    var token = 'df39d56eaa83cf94ef546cebdfb31241327e62f8712ddc4fad0297e8de746f62'; 
    $http.defaults.headers.common["Authorization"] = 'Bearer ' + token; 

    var resource = $resource(
     'http://localhost:port/devices/:id', 
     { port: ':3001', id: '@id' }, 
     { update: { method: 'PUT' } } 
    ); 

    return resource; 
    }]); 

這裏的應用程序代碼。

'use strict'; 

angular.module('lelylan', ['lelylan.services', 'lelylan.directives']) 

而這裏的index.html。

<!doctype html> 
<html lang="en" ng-app="lelylan"> 
    <head> 
    <meta charset="utf-8"> 
    <title>Lelylan Components</title> 
    <link rel="stylesheet" href="css/app.css"/> 
    </head> 
    <body> 

    <device id="50c61ff1d033a9b610000001"></device> 

    <!-- In production use: <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script> --> 
    <script src="lib/angular/angular.js"></script> 
    <script src="lib/angular/angular-resource.js"></script> 
    <script src="js/app.js"></script> 
    <script src="js/services.js"></script> 
    <script src="js/directives.js"></script> 
    </body> 
</html> 

閱讀Angular documentation和嘗試不同的解決方案後,我想出了以下 測試中我試圖嘲弄我的後端請求。問題是請求仍然會觸及真正的服務。它 看起來像我不能攔截請求。

// e2e test 
'use strict'; 

describe('directives', function() { 

    var resource = { id: '1', uri: 'http://localhost:3001/devices/1' }; 
    var myAppDev = angular.module('myAppDev', ['lelylan', 'ngMockE2E']); 

    myAppDev.run(function($httpBackend) { 
    $httpBackend.when('GET', 'http://localhost:3001/devices/1').respond(resource); 
    $httpBackend.when('GET', /\/templates\//).passThrough(); 
    }); 

    beforeEach(function() { 
    browser().navigateTo('../../app/index.html'); 
    }); 

    describe('when renders a device', function() { 

    it('renders the title', function() { 
     expect(element('.device .name').text()).toEqual('Closet dimmer'); 
    }); 

    it('renders the last time update', function() { 
     expect(element('.device .updated-at').text()).toEqual('2012-12-20T18:40:19Z'); 
    }) 
    }); 
}); 

我想我錯過了一些配置,但我無法真正理解哪些配置。 非常感謝。

回答

1

閱讀this question中的最後一條評論我帶來了最終解決方案。

其實我錯過了一個重要的步驟,因爲我不得不使用一個使用模擬應用程序的HTML文件。讓我們讓代碼說話。

1)我用測試環境創建了一個HTML文件。主要區別在於我設置了ng-app = test並添加了兩個新的JS文件。第一個是/test/e2e/app-test.js,我創建了測試模塊,第二個是/test/lib/angular-mocks.js。

<!doctype html> 
<html lang="en" ng-app="test"> 
    <head> 
    <meta charset="utf-8"> 
    <title>Lelylan Test</title> 
    <link rel="stylesheet" href="css/app.css"/> 
    </head> 
    <body> 

    <device id="1"></device> 

    <script src="lib/angular/angular.js"></script> 
    <script src="lib/angular/angular-resource.js"></script> 
    <script src="js/app.js"></script> 
    <script src="js/settings.js"></script> 
    <script src="js/services.js"></script> 
    <script src="js/controllers.js"></script> 
    <script src="js/filters.js"></script> 
    <script src="js/directives.js"></script> 

    <!-- Test application with mocked requests --> 
    <script src="../test/e2e/app-test.js"></script> 
    <script src="../test/lib/angular/angular-mocks.js"></script> 
    </body> 
</html> 

現在,讓我們看看我們如何實現測試模塊。在這裏,我定義了一個完全與我的主模塊(lelylan)相同的模塊,並添加了ngMockE2E,它允許您訪問$ httpBackend並模擬HTTP請求。

'use strict'; 

var resource = { id: '1', uri: 'http://localhost:3001/devices/1' }; 

var test = angular.module('test', ['lelylan', 'ngMockE2E']); 

test.run(function($httpBackend) { 
    $httpBackend.when('GET', 'http://localhost:3001/devices/1').respond(resource); 
    $httpBackend.when('GET', /\/templates\//).passThrough(); 
}); 

沒有更多。運行腳本/ e2e-test.sh,你就完成了。

+0

那麼我需要在這個新的測試html文件中複製所有應用程序的現有html嗎?我們可以在單元測試中將$ httpBackend包含在e2e測試中,而不需要修改實際的應用程序嗎? – EdL

+0

要回答我自己的問題 - 如果您的所有html都在一個文件中,並且您沒有使用路由和部分模板,那麼是的,您需要複製您的html文件以獲得測試版本。你不需要改變你的app.js,你可以添加一個包含ngMockE2E的test-app.js。目前似乎不可能只修改scenario.js。我找到的最佳示例:https://github.com/stephennancekivell/angular_e2e_http/tree/ngMockE2E – EdL