我已经装饰了Angular的简单$ log实现,因此我可以在特定级别登录。
/**
* There are 7 Application logging levels which are:
* OFF: 0,
* ERROR: 20,
* WARN: 30,
* INFO: 40,
* DEBUG: 50,
* LOG: 60,
* ALL: 100
*
* To set the logging level to debug:
* currentLogLevel = LOG_LEVEL.DEBUG;
*
* Set it to error:
* currentLogLevel = LOG_LEVEL.ERROR;
*
* ERROR -> ERROR
* WARNING -> WARNING & ERROR
* INFO -> INFO, WARNING & ERROR
* DEBUG -> DEBUG, INFO, WARNING & ERROR
* LOG -> LOG, DEBUG, INFO, WARNING & ERROR
*/
angular.module( 'Logger' ).config( function( $provide ) {
$provide.decorator( '$log', function( $delegate, LOG_LEVEL ) {
var currentLogLevel = LOG_LEVEL.WARNING, // Will only log warnings & errors
log = $delegate.log,
debug = $delegate.debug,
info = $delegate.info,
warn = $delegate.warn,
error = $delegate.error;
function attemptToLog( requestLevel, msg ) {
if( currentLogLevel >= LOG_LEVEL[requestLevel] ) {
switch( requestLevel ) {
case 'LOG': log( msg );
break;
case 'DEBUG': debug( msg );
break;
case 'INFO': info( msg );
break;
case 'WARN': warn( msg );
break;
case 'ERROR': error( msg );
break;
}
}
}
$delegate.log = function( msg ) {
attemptToLog( 'LOG', msg );
};
$delegate.debug = function( msg ) {
attemptToLog('DEBUG', msg);
};
$delegate.info = function( msg ) {
attemptToLog('INFO', msg );
};
$delegate.warn = function( msg ) {
attemptToLog( 'WARN', msg );
};
$delegate.error = function( msg ) {
attemptToLog( 'ERROR', msg );
};
return $delegate;
});
以下是日志级别:
angular.module( 'Logger' )
.constant('LOG_LEVEL', {
OFF: 0,
ERROR: 20,
WARN: 30,
INFO: 40,
DEBUG: 50,
LOG: 60,
ALL: 100
});
一切都很好。我遇到的问题是如何测试它。到目前为止,我有这个:
describe('Testing a decorator', function() {
var log;
beforeEach(module('Logger'));
beforeEach(module(function ($provide) {
$provide.decorator('$log', function ($delegate) {
['log', 'debug', 'info', 'warn', 'error'].forEach(function(logLevel) {
$delegate[logLevel].logs = [];
});
return $delegate;
});
}));
beforeEach(inject(function (_$log_) {
log = _$log_;
}));
it('should log warn', function () {
log.warn('Logging message');
// Expect warn to be logged
});
it('should log error', function () {
log.error('Logging message');
// Expect error to be logged
});
it('should not log anything', function () {
log.info('Logging message');
// Expect no logging whatsoever
});
});
我真的不知道如何测试这个,所以任何想法都会很棒。也许我必须改变实施。
另外,我需要一种更好的方法来设置当前的日志级别,但是,我只限于常量。目前我无法想到更好/更灵活的解决方案。
干杯。
更新:我找到了一个很好的解决方案:
describe('Testing a decorator', function() {
beforeEach(module('Logger'));
beforeEach(module(function ($provide) {
$provide.decorator('$log', function ($delegate) {
['log', 'debug', 'info', 'warn', 'error'].forEach(function(logLevel) {
$delegate[logLevel].logs = [];
});
return $delegate;
});
}));
describe('Logging at the various levels (log, debug, info, warn, error)', function() {
beforeEach(inject(function ($log) {
$log.log('log');
$log.debug('debug');
$log.info('info');
$log.warn('warn');
$log.error('error');
}));
it('should only log an error when the log level is ERROR', inject(function($log) {
expect($log.log.logs.length).toBe(0);
expect($log.debug.logs.length).toBe(0);
expect($log.info.logs.length).toBe(0);
expect($log.warn.logs.length).toBe(0);
expect($log.error.logs.length).toBe(1);
}));
it('should log an error and warn when the log level is WARN', inject(function($log) {
expect($log.log.logs.length).toBe(0);
expect($log.debug.logs.length).toBe(0);
expect($log.info.logs.length).toBe(0);
expect($log.warn.logs.length).toBe(1);
expect($log.error.logs.length).toBe(1);
}));
it('should log an error, warn and info when the log level is INFO', inject(function($log) {
expect($log.log.logs.length).toBe(0);
expect($log.debug.logs.length).toBe(0);
expect($log.info.logs.length).toBe(1);
expect($log.warn.logs.length).toBe(1);
expect($log.error.logs.length).toBe(1);
}));
it('should log an error, warn, info and debug when the log level is DEBUG', inject(function($log) {
expect($log.log.logs.length).toBe(0);
expect($log.debug.logs.length).toBe(1);
expect($log.info.logs.length).toBe(1);
expect($log.warn.logs.length).toBe(1);
expect($log.error.logs.length).toBe(1);
}));
it('should log an error, warn, info, debug and info when the log level is LOG', inject(function($log) {
expect($log.log.logs.length).toBe(1);
expect($log.debug.logs.length).toBe(1);
expect($log.info.logs.length).toBe(1);
expect($log.warn.logs.length).toBe(1);
expect($log.error.logs.length).toBe(1);
}));
});
});
我只需要弄清楚如何在每次测试开始时设置currentLogLevel然后我就完成了。再一次,任何想法?
最终更新:我设法为每个测试用例配置一个新的LOG_LEVEL常量。
function attemptToLog( requestLevel, msg ) {
if ( LOG_LEVEL.CURRENT_LOG_LEVEL >= LOG_LEVEL[requestLevel] ) {
...
}
....
mockLogLevel = {
OFF: 0,
ERROR: 20,
WARN: 30,
INFO: 40,
DEBUG: 50,
LOG: 60,
ALL: 100,
CURRENT_LOG_LEVEL: 100
};
...
describe('logging when the level is set to ERROR', function() {
beforeEach(module(function ($provide) {
mockLogLevel.CURRENT_LOG_LEVEL = mockLogLevel.ERROR;
$provide.constant('LOG_LEVEL', mockLogLevel);
}));
beforeEach(inject(function ($log) {
logEverything($log);
}));
it('should log error only', inject(function($log) {
expect($log.log.logs.length).toBe(0);
expect($log.debug.logs.length).toBe(0);
expect($log.info.logs.length).toBe(0);
expect($log.warn.logs.length).toBe(0);
expect($log.error.logs.length).toBe(1);
}));
});
....
function logEverything($log) {
$log.log('log');
$log.debug('debug');
$log.info('info');
$log.warn('warn');
$log.error('error');
}