我正在尝试对通过异步服务获取一些已翻译字符串的控制器进行单元测试,但我在Jasmine vs Promises中遗漏了一些内容......
让我们从错误开始,即:
TypeError: 'undefined' is not an object (evaluating 'i18n.get('navigation').then')
测试用例
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new()
}))
it('should invoke the i18n service for translations', inject(function ($controller, i18n) {
spyOn(i18n, 'get')
var HeaderCtrl = $controller('HeaderCtrl', {
$scope: scope,
i18n: i18n
})
expect(i18n.get).toHaveBeenCalledWith('navigation')
}))
控制器
.controller('HeaderCtrl', function ($scope, i18n) {
// removing the '.then' part makes the test pass,
// which makes me almost sure that my missing is in the promise mamnagement
i18n.get('navigation').then(
function (data) {
$scope.strings = data
},
function (err) {
console.log(err)
})
异步服务
get: function (key) {
var deferred = $q.defer()
$http.get('locale/en.json')
.success(function (data) {
deferred.resolve(data[key])
})
.error(function (err, status) {
deferred.reject(err, status)
})
return deferred.promise
}
我也尝试添加一些$http
模拟,但无济于事
使用$ http模拟测试
beforeEach(inject(function ($rootScope, $httpBackend) {
scope = $rootScope.$new()
$httpBackend.whenGET('locale/en.json')
.respond(enStrings)
}))
it('should invoke the i18n service for translations', inject(function ($controller, i18n) {
spyOn(i18n, 'get')
var HeaderCtrl = $controller('HeaderCtrl', {
$scope: scope,
i18n: i18n
})
$httpBackend.flush()
expect(i18n.get).toHaveBeenCalledWith('navigation')
}))
答案 0 :(得分:2)
我终于绕过这个 希望这个答案对其他人有帮助。
我所需要的只是一个嘲笑的承诺,而不是真正的回归:
// Initialize the controller and a mock scope
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new()
}))
it('should invoke the i18n service for translations', inject(function ($controller, i18n) {
var fakePromise = function () {
return {
then: function (ok, err) {},
success: function (ok) {},
error: function (err) {}
}
}
// when i18n.get('navigation') gets called, return my fake promise
spyOn(i18n, 'get').andCallFake(fakePromise)
var HeaderCtrl = $controller('HeaderCtrl', {
$scope: scope,
i18n: i18n
})
expect(i18n.get).toHaveBeenCalledWith('navigation')
}))