我有以下功能实现
function getRepo(url) {
var repos = {};
if (repos.hasOwnProperty(url)) {
return repos[url];
}
return $.get(url)
.then(repoRetrieved)
.fail(failureHandler);
function repoRetrieved(data) {
return repos[url] = data;
}
function failureHandler(err, xhr) {
throw new Error(xhr.responseText);
}
}
我写了以下测试:
describe('"getRepo" method', function() {
var getDeffered;
var $;
beforeEach(function() {
getDeffered = Q.defer();
$ = jasmine.createSpyObj('$', ['get']);
$.get.and.returnValue(getDeffered.promise);
});
it('should return a promise', function(){
expect(getRepo('someURL')).toEqual(getDeffered.promise);
});
});
此测试失败。我想是因为我称之为then方法。
如果函数实现是:
,它不会失败function getRepo(url) {
return $.get(url);
}
这是使用Q.defer()
时jasmine抛出的消息Expected { promiseDispatch : Function, valueOf : Function, inspect : Function }
to equal { promiseDispatch : Function, valueOf : Function, inspect : Function }.
如果我使用jQuery Deferred:
,这就是消息Expected { state : Function, always : Function, then : Function, promise : Function, pipe : Function, done : Function, fail : Function, progress : Function }
to equal { state : Function, always : Function, then : Function, promise : Function, pipe : Function, done : Function, fail : Function, progress : Function }.
jQuery延期测试实现:
describe('"getRepo" method', function() {
var getDeffered;
var $;
beforeEach(function() {
getDeffered = real$.Deferred();
$ = jasmine.createSpyObj('$', ['get']);
$.get.and.returnValue(getDeffered.promise());
});
it('should return a promise', function(){
expect(getRepo('someURL')).toEqual(getDeffered.promise());
});
});
答案 0 :(得分:1)
您可以直接测试已解析的值,而不是将返回的对象作为承诺进行测试,从而获得更准确的结果:
describe('"getRepo" method', function() {
var originalGet;
beforeAll(function() {
originalGet = $.get;
});
beforeEach(function() {
$.get = originalGet; // Restore original function
});
it('should update the data[] array when resolved', function(done) {
// This is an asynchronous test, so we need to pass done ^^^^
var expectedResult = 'test data';
$.get = function() {
var dfd = $.Deferred();
dfd.resolve(expectedResult);
return dfd.promise();
};
getRepo('someURL').then(function(repos) {
var actualResult = repos['someUrl'];
expect(actualResult).toEqual(expectedResult);
done(); // This is an asynchronous test. We must mark the test as done.
});
});
});
请注意,jQuery的Promise实现非常糟糕。最好是使用本机Promises或像Bluebird这样的库。
答案 1 :(得分:0)
您正在创建一个本地$
变量,然后为其分配一个间谍对象。这与$
使用的getRepo
不同。
您应该删除本地变量var $;
并模拟原始$.get
。
试试这个:
describe('"getRepo" method', function() {
var testPromise;
beforeEach(function() {
testPromise = real$.Deferred().promise();
spyOn($, 'get').andCallFake(function() {
return testPromise;
});
});
it('should return a promise', function(){
expect(getRepo('someURL')).toEqual(testPromise);
});
});