【发布时间】:2016-12-26 13:45:24
【问题描述】:
节日快乐!我遇到了一个我不知道为什么会出现的问题:
//登录控制:
angular.module('login.controller', [])
.controller('LoginCtrl', function($scope, $state, $translate, $ionicPopup, UserService, Auth) {
// With the new view caching in Ionic, Controllers are only called
// when they are recreated or on app start, instead of every page change.
// To listen for when this page is active (for example, to refresh data),
// listen for the $ionicView.enter event:
//$scope.$on('$ionicView.enter', function(e) {
//});
// Form data for the login modal
$scope.loginData = {};
// Perform the login action when the user submits the login form
$scope.doLogin = function() {
var onSuccess = function(response) {
if (response.data.user !== null) {
Auth.setUser(response.data.user);
Auth.setToken(response.data.user.token);
$state.go('app.main');
} else if (response.data.result == 101) {
$ionicPopup.alert({
title: $translate.instant('login_error'),
template: $translate.instant('login_not_verified')
});
}else {
$ionicPopup.alert({
title: $translate.instant('login_error'),
template: $translate.instant('login_bad_password_text')
});
}
};
var onError = function() {
$ionicPopup.alert({
title: $translate.instant('login_error'),
template: $translate.instant('login_error_text')
});
};
console.log('Doing login', $scope.loginData);
UserService.login($scope.loginData.username, $scope.loginData.password).then(onSuccess, onError);
};
$scope.doRegister = function() {
$state.go("register");
};
});
//登录Ctrl测试
describe('LoginCtrl', function() {
var controller,
deferredLogin,
userServiceMock,
stateMock,
scopeMock,
ionicPopupMock;
//Load the App module
beforeEach(module('starter'));
// Instantiate the Controller and Mocks
beforeEach(inject(function($controller, $q, $rootScope, $translate, Auth) {
deferredLogin = $q.defer();
scopeMock = $rootScope.$new();
// mock userServiceMock
userServiceMock = {
login: jasmine.createSpy('login spy')
.and.returnValue(deferredLogin.promise)
};
//mock $state
stateMock = jasmine.createSpyObj('$state spy', ['go']);
//mock $ionicPopup
ionicPopupMock = jasmine.createSpyObj('$ionicPopup spy', ['alert']);
//Instantiate LoginCtrl
controller = $controller('LoginCtrl', {
'$scope' : scopeMock,
'$state' : stateMock,
'$translate' : $translate,
'$ionicPopup' : ionicPopupMock,
'UserService' : userServiceMock,
'Auth' : Auth
});
}));
describe('#doLogin', function() {
// Call doLogin on the Controllers
beforeEach(inject(function(_$rootScope_) {
$rootScope = _$rootScope_;
controller.$scope.loginData.username = 'test';
controller.$scope.loginData.password = 'password';
controller.$scope.doLogin();
}));
it('should call login on userService', function() {
expect(userServiceMock.login).toHaveBeenCalledWith('test','password');
});
describe('when the login is executed,', function() {
it('if successful, should change state to app.main', function() {
//TODO: Mock the login response from userService
expect(stateMock.go).toHaveBeenCalledWith('app.main');
});
it('if unsuccessful, should show popup', function() {
//TODO: Mock the login response from userService
expect(ionicPopup.alert).toHaveBeenCalled();
});
});
});
});
问题是当我执行测试时它执行expect(userServiceMock.login).toHaveBeenCalledWith('test','password');它给了我以下错误:
TypeError: undefined is not an object (evalating 'userServiceMock.login') in unit-tests/login.controller.tests.js(第 56 行)
我不知道 userServiceMock 给了我 undefined。
谢谢大家,如果您需要更多代码或其他内容,请告诉我。
这是我的因果报应:
// Karma configuration
// Generated on Mon Dec 26 2016 10:38:06 GMT+0100 (CET)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
'../www/lib/ionic/js/ionic.bundle.js',
'../www/js/**/*.js',
'../www/lib/angular-mocks/angular-mocks.js',
'../www/lib/angular-translate/angular-translate.js',
'../www/lib/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
'unit-tests/**/*.js'
],
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress'],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
});
};
【问题讨论】:
-
有可能
beforeEach有错误,所以没有分配mock对象。控制台中没有其他错误吗? PhantomJS 以吞咽错误着称,尝试将其更改为 Chrome 启动器。 -
抱歉耽搁了,我现在试试
-
@estus 问题是翻译 js 没有在 conf 中定义。但是现在又报错了,问题是控制器没有初始化,不知道为什么。
-
问题依旧。应该有一个错误说明问题所在。如果没有,那就归咎于 PhantomJS。
-
@estus 我将其更改为 Chrome,但问题是所有变量都已初始化,但是当我记录变量控制器的日志时,我在日志中得到一个“{}”
标签: angularjs unit-testing jasmine karma-runner karma-jasmine