TypeError: 'undefined' 不是函数(评估 '$scope.$dismiss()')
Posted
技术标签:
【中文标题】TypeError: \'undefined\' 不是函数(评估 \'$scope.$dismiss()\')【英文标题】:TypeError: 'undefined' is not a function (evaluating '$scope.$dismiss()')TypeError: 'undefined' 不是函数(评估 '$scope.$dismiss()') 【发布时间】:2016-05-18 23:49:54 【问题描述】:我需要使用 karma 单元测试来测试我的登录过程,但是在执行测试时我遇到了一个错误。
我的登录控制器代码:
$scope.signin = function (valid)
if (valid)
$http.post('/auth/signin', $scope.credentials).success(function (response)
console.log(response)
// If successful we assign the response to the global user model
$scope.authentication.user = response.user;
localStorage.setItem('token',response.token.logintoken);
// And redirect to the index page
$scope.$dismiss();
).error(function (response)
$scope.error = response.message;
);
else
$scope.userSigninrequredErr = true;
;
Karma 测试代码:
(function ()
// Authentication controller Spec
describe('AuthenticationController', function ()
// Initialize global variables
var AuthenticationController,
scope,
$httpBackend,
$stateParams,
$cookieStore,
notify,
$location,
modal;
beforeEach(function ()
jasmine.addMatchers(
toEqualData: function (util, customEqualityTesters)
return
compare: function (actual, expected)
return
pass: angular.equals(actual, expected)
;
;
);
);
// Load the main application module
beforeEach(module(ApplicationConfiguration.applicationModuleName));
// The injector ignores leading and trailing underscores here (i.e. _$httpBackend_).
// This allows us to inject a service but then attach it to a variable
// with the same name as the service.
beforeEach(inject(function ($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_, _$cookieStore_, _notify_)
// Set a new global scope
scope = $rootScope.$new();
// Point global variables to injected services
$stateParams = _$stateParams_;
$httpBackend = _$httpBackend_;
$cookieStore = _$cookieStore_;
notify = _notify_;
$location = _$location_;
modal = jasmine.createSpyObj('modal', ['show', 'hide']);
// Initialize the Authentication controller
AuthenticationController = $controller('AuthenticationController',
$scope: scope
);
));
it('$scope.signin() should login with a correct user and password', function ()
// Test expected GET request user: 'Fred', token: logintoken: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9'
scope.credentials.user = 'jenson';
scope.credentials.token = logintoken: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9';
$httpBackend.when('POST', '/auth/signin').respond(200, scope.credentials);
scope.signin(true);
$httpBackend.when('GET', /\.html$/).respond('');
$httpBackend.flush();
// Test scope value
expect(scope.credentials.user).toEqual('jenson');
expect($location.url()).toEqual('/dashboard');
);
执行 karma 测试后,我得到了正确的响应,但 devtools 控制台中显示以下错误。
TypeError: 'undefined' is not a function (evalating '$scope.$dismiss()')
感谢任何帮助。谢谢。
【问题讨论】:
您能显示AuthenticationController
代码的其余部分吗?$scope.$dismiss()
是在哪里定义的?还是这个控制器通常通过模态服务运行?
$dismiss 已在模态范围内可用,控制器中未使用任何 mroe 函数
$dismiss(reason) (Type: function) - 一种可以用来关闭模式的方法,传递一个原因。
【参考方案1】:
所以问题在于,在“真实”代码中,模态服务正在调用控制器并为您创建一个新范围,在其上填充 $dismiss()
方法,但在您的单元测试中,您正在手动调用控制器(使用$controller
服务),意味着没有$scope.$dismiss()
函数,因此报错。
相反,您需要执行您在真实代码中所做的事情,并使用模态服务来实例化您的控制器,或者至少模仿模态服务所做的并在您的新作用域上添加一些存根函数,包括$dismiss()
.
【讨论】:
感谢 gregl 的宝贵回答,这里我将 $modalinstance 传递给控制器并使用了 $modalInstance.dismiss('cancel');用于丢弃弹出窗口。以上是关于TypeError: 'undefined' 不是函数(评估 '$scope.$dismiss()')的主要内容,如果未能解决你的问题,请参考以下文章
Selenium / PhantomJS:无法发送send_keys(TypeError - undefined不是函数)
TypeError:“未定义”不是函数(评估“$(文档)”)
NetworkStatus0 = TypeError:“未定义”不是函数
模块承诺:UnhandledPromiseRejectionWarning:TypeError:无法读取undefined的属性'collection'
解决 “TypeError: Cannot read properties of undefined (reading ‘xxx‘)“