【问题标题】:testing angularjs 1 factory method is automatically called inside a controller with jasmine测试 angularjs 1 工厂方法在 jasmine 控制器内部自动调用
【发布时间】:2018-08-31 02:54:20
【问题描述】:

我正在使用带有 angularjs 的 ruby​​ on rails,第一次使用 teaspoon-jasmine 对其进行测试,但遇到了问题。基本上,我有一个控制器,它创建一个空数组,并在加载时调用工厂方法来填充该数组。 Factory 发出 http 请求并返回数据。现在,我正在尝试测试控制器,并且我正在尝试测试 1)在加载控制器时调用工厂方法,以及 2)控制器通过其回调正确分配返回的数据。有一段时间我很难让一个模拟工厂通过测试,但是一旦我做到了,我意识到我实际上并没有再测试我的控制器了,但是下面的代码通过了。关于我如何仍然可以通过模拟、承诺/回调传递它的任何提示,但准确地测试我的控制器功能。或者我什至应该在我的控制器中测试这个,因为它调用工厂方法并只是给它一个回调?我的3个文件如下。任何人都可以在这里帮忙吗?将不胜感激

mainController.js

'use strict';


myApp.controller('mainController', [ 'mainFactory', '$scope', '$resource', function(factory, scope, resource){

	//hits the /games server route upon page load via the factory to grab the list of video games
	scope.games = [];

	factory.populateTable(function(data){
		scope.games = data;
	});



}]);

mainFactory.js

'use strict';


myApp.factory('mainFactory', ['$http', '$routeParams', '$location', function(http, routeParams, location) {
	var factory = {};

	factory.populateTable = function(callback) {
			http.get('/games')
			.then(function(response){
				callback(response.data);
			})
	};


	return factory;
}]);

最后是我的 mainController_spec.js 文件

'use strict';

describe("mainController", function() {

	var scope,
			ctrl,
			deferred,
			mainFactoryMock;

	var gamesArray = [
		{name: 'Mario World', manufacturer: 'Nintendo'},
		{name: 'Sonic', manufacturer: 'Sega'}
	];

	var ngInject = angular.mock.inject;
	var ngModule = angular.mock.module;


	var setupController = function() {
		ngInject( function($rootScope, $controller, $q) {
			deferred = $q.defer();
			deferred.resolve(gamesArray);

			mainFactoryMock = {
				populateTable: function() {}
			};

			spyOn(mainFactoryMock, 'populateTable').and.returnValue(deferred.promise);

			scope = $rootScope.$new();
      ctrl = $controller('mainController', {
				mainFactory: mainFactoryMock,
				$scope: scope
			});
    })
	}

	beforeEach(ngModule("angularApp"));

	beforeEach(function(){
		setupController();
	});

	it('should start with an empty games array and populate the array upon load via a factory method', function(){
		expect(scope.games).toEqual([])

		mainFactoryMock.populateTable();

		expect(mainFactoryMock.populateTable).toHaveBeenCalled();
		
		mainFactoryMock.populateTable().then(function(d) {
        scope.games = d;
    });
    scope.$apply();  // resolve promise
		expect(scope.games).toEqual(gamesArray)
	})

});

【问题讨论】:

    标签: javascript angularjs jasmine controllers angular-mock


    【解决方案1】:

    您的代码看起来“非标准”,例如仍在使用范围。

    如果您刚开始使用 Angular,我几乎不建议您阅读并遵循以下内容:

    https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md

    Angular 控制器无法测试,将逻辑提取到工厂/服务中并从那里进行测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-20
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 2018-01-20
      • 2016-04-20
      • 1970-01-01
      相关资源
      最近更新 更多