我正在尝试在我的控制器中测试一个函数,该函数在采取任何操作之前首先监视要加载的字典。
我得到的问题是我的测试失败,因为手表似乎没有运行。
我的控制器功能
function setPageTitle(title) {
$rootScope.$watch('dictionary', function(dictionary) {
if (dictionary) {
if ($location.$$path != '/dashboard') {
$rootScope.pageTitle = $rootScope.dictionary.pageTitles[title] || $rootScope.dictionary.pageTitles.dashboard || 'Dashboard';
} else {
$rootScope.pageTitle = $rootScope.dictionary.pageTitles.dashboard || 'Dashboard';
}
}
});
}
我的测试...
describe('AppController function', function() {
var rootScope, scope, $location, $window, controller, createController, cacheFactory, toastr;
beforeEach(module('mockedDashboard'));
beforeEach(inject(function(_$rootScope_, $controller, _$location_, _$window_, _toastr_, _$timeout_) {
$location = _$location_;
$window = _$window_;
$timeout = _$timeout_;
scope = _$rootScope_.$new();
rootScope = _$rootScope_;
toastr = _toastr_;
createController = function() {
return $controller('AppController', {
'$scope': scope
});
};
controller = createController();
}));
// We are using CacheFactory in this project, when running multiple tests on the controller
// we need to destroy the cache for each test as the controller is initialized for each test.
afterEach(inject(function(_CacheFactory_) {
cacheFactory = _CacheFactory_;
cacheFactory.destroy('defaultCache');
}));
describe('setPageTitle()', function() {
it('should update the $rootScope.pageTitle', function() {
scope.setPageTitle('logIn');
scope.$apply();
expect(rootScope.pageTitle).toBe('LOG IN');
});
});
});
失败消息
永远不会设置预计未定义为'登录'
rootScope.pageTitle
,因为当测试调用函数时手表不会运行。我怎么能绕过这个?
我试过scope.$apply()
我读过的应该会触发$ watch,但它仍然不起作用。
修改 我尝试使用done函数,但是测试仍然失败,因为rootScope.pageTitle仍然显示为未定义。 3000ms应该有足够的时间来工作,通常这样做的时间少于500毫秒。 (我也知道代码有效,因为这个测试写的太晚了)
describe('setPageTitle()', function() {
it('should update the $rootScope.pageTitle', function(done) {
scope.setPageTitle('logIn');
scope.$apply();
setTimeout(function() {
// console.log('dictionary: ' + rootScope.dictionary.pageTitles.logIn);
console.log('rootScope.pageTitle: ' + rootScope.pageTitle);
expect(rootScope.pageTitle).toBe('LOG IN');
// expect(true).toBe(false);
done();
}, 3000);
});
});
答案 0 :(得分:0)
看起来你的测试是同步测试,因此Karma认为一旦函数返回就完成了。不幸的是,实际情况并非如此,因为您需要等待$apply
的影响发生,这需要另一次通过事件循环。您需要通过添加done
参数将测试转换为异步测试,并在触发监视后以某种方式调用它。
it('description', function(done) {
// do your setup things here
scope.$apply();
setTimeout(function() {
// make your assertions here
done()
}, 25);
})
当然,使用setTimeout
是一种非常难看的方式来等待必要的时间,如果还有其他一些你可以注意的事件,它会更优雅。
答案 1 :(得分:0)
嗯,很明显 - 你的测试失败了,因为代码$rootScope.$watch('dictionary', function(dictionary) {
if (dictionary) {
...
}
});
没有运行。
$rootScope.dictionary
由于没有明确设置用于测试目的,undefined
describe('setPageTitle()', function() {
it('should update the $rootScope.pageTitle', function() {
scope.setPageTitle('logIn');
rootScope.dictionary = {
'whatever you': 'need here'
};
scope.$apply();
expect(rootScope.pageTitle).toBe('LOG IN');
});
});
可能存在问题。
试试这个
$digest
顺便说一句 - 完全没有必要使用异步测试用例,因为scope.$apply();
将在>>> s = 'a;;b;;;c;;;;d'
>>> pattern = ';{2,}'
>>> def f(m):
return m.group(0)[1:]
>>> re.sub(pattern, f, s)
'a;b;;c;;;d'
>>>
行同步调用。
答案 2 :(得分:0)
对您的测试用例进行的少量更改很少,您可以尝试一下,
describe('setPageTitle()', function() {
it('should update the $rootScope.pageTitle', function() {
rootScope.dictionary = "someValue"; // As you were watching this object assign some value and then apply $digest
// Instead of $apply use $digest with rootscope
rootscope.$digest();
expect(rootScope.pageTitle).toBe('LOG IN');
});
});