2019独角兽企业重金招聘Python工程师标准>>>
测试目的
- 测试controller是否被正确执行
- 测试所有的 $scope 成员变量被正确设置
- 在单元测试中使用 mock 抓取 XHR 请求。
测试 controller 需要知道,通过 controller 的 scope 会传什么数据到模板中。因此你需要先测试一下 controller 它自己是否正常工作,然后再测试一下数据是否绑到模板中。最好是知道在 controller 执行的时候,你希望 scope 中应该有什么值。如果你想写单元测试,那么它依赖 controller 中的逻辑。E2E 测试也可以,但是你不能保证 controller 工作正常。所以这章的测试,最好是使用 Midway 测试。
单元测试
<!-- lang: js -->
//
// test/unit/controllers/controllersSpec.js
//
describe("Unit: Testing Controllers", function() {beforeEach(module('App'));it('should have a VideosCtrl controller', function() {expect(App.VideosCtrl).not.to.equal(null);});it('should have a VideoCtrl controller', function() {expect(App.VideoCtrl).not.to.equal(null);});it('should have a WatchedVideosCtrl controller', function() {expect(App.WatchedVideosCtrl).not.to.equal(null);});it('should have a properly working VideosCtrl controller', inject(function($rootScope, $controller, $httpBackend) {var searchTestAtr = 'cars';var response = $httpBackend.expectJSONP('https://gdata.youtube.com/feeds/api/videos?q=' + searchTestAtr + '&v=2&alt=json&callback=JSON_CALLBACK');response.respond(null);var $scope = $rootScope.$new();var ctrl = $controller('VideosCtrl', {$scope : $scope,$routeParams : {q : searchTestAtr}});}));it('should have a properly working VideoCtrl controller', inject(function($rootScope, $controller, $httpBackend) {var searchID = 'cars';var response = $httpBackend.expectJSONP('https://gdata.youtube.com/feeds/api/videos/' + searchID + '?v=2&alt=json&callback=JSON_CALLBACK');response.respond(null);var $scope = $rootScope.$new();var ctrl = $controller('VideoCtrl', {$scope : $scope,$routeParams : {id : searchID}});}));it('should have a properly working WatchedVideosCtrl controller', inject(function($rootScope, $controller, $httpBackend) {var $scope = $rootScope.$new();//we're stubbing the onReady event$scope.onReady = function() { };var ctrl = $controller('WatchedVideosCtrl', {$scope : $scope});}));});
Midway 测试
<!-- lang: js -->
//
// test/midway/controllers/controllersSpec.js
//
describe("Midway: Testing Controllers", function() {var tester;beforeEach(function() {if(tester) {tester.destroy();}tester = ngMidwayTester('App');});it('should load the VideosCtrl controller properly when /videos route is accessed', function(done) {tester.visit('/videos', function() {tester.path().should.eq('/videos');var current = tester.inject('$route').current;var controller = current.controller;var scope = current.scope;expect(controller).to.eql('VideosCtrl');done();});});it('should load the WatchedVideosCtrl controller properly when /watched-videos route is accessed', function(done) {tester.visit('/watched-videos', function() {tester.path().should.eq('/watched-videos');var current = tester.inject('$route').current;var controller = current.controller;var params = current.params;var scope = current.scope;expect(controller).to.equal('WatchedVideosCtrl');done();});});});
E2E 测试
<!-- lang: js -->
//
// test/e2e/controllers/controllersSpec.js
//
describe("E2E: Testing Controllers", function() {beforeEach(function() {browser().navigateTo('/');});it('should have a working videos page controller that applies the videos to the scope', function() {browser().navigateTo('#/');expect(browser().location().path()).toBe("/videos");expect(element('#ng-view').html()).toContain('data-app-youtube-listings');});it('should have a working video page controller that applies the video to the scope', function() {browser().navigateTo('#/videos/WuiHuZq_cg4');expect(browser().location().path()).toBe("/videos/WuiHuZq_cg4");expect(element('#ng-view').html()).toContain('app-youtube-embed');});});