如何使用Jasmine模拟jQuery

che*_*ica 6 jquery jasmine jasmine-jquery

我想做什么:我们正在为使用jQuery的现有Javascript代码库编写一些测试.对于测试,我们不希望有实际的HTML元素(HTML fixture).如果我们有一个不与HTML相关的jQuery模拟对象,我们更喜欢它.

我的出发点:我在这里找到的最有希望的方法:

http://eclipsesource.com/blogs/2014/03/27/mocks-in-jasmine-tests/

这将创建一个辅助方法,通过遍历对象的函数并为每个函数创建间谍来创建模拟:

window.mock = function (constr, name) {
  var keys = [];
  for (var key in constr.prototype)
    keys.push( key );
  return keys.length > 0 ? jasmine.createSpyObj( name || "mock", keys ) : {};
};
Run Code Online (Sandbox Code Playgroud)

然后,如果我正确地理解他,他就会使用这个(他在博客文章中改编的例子):

var el = mock($);
el('.some-not-existing-class').css('background', 'red');
expect(el.css).toHaveBeenCalledWith('background', 'red');
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为它el是一个object而不是一个function.

我的方法来解决这个问题:我重构自己的mock功能,考虑到该案件constrfunction:

mock (constr, name) {
  var keys = [];
  for (var key in constr.prototype)
    keys.push(key);
  var result = keys.length > 0 ? jasmine.createSpyObj(name || "mock", keys) : {};

  // make sure that if constr is a function (like in the case of jQuery), the mock is too
  if (typeof constr === 'function') {
    var result2 = result;
    result = jasmine.createSpy(name || 'mock-fn');
    for (var key in result2)
      result[key] = result2[key];
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)

但是,测试中的第二行会引发Cannot read property css of undefined错误:

var el = mock($);
el('.some-not-existing-class').css('background', 'red');
expect(el.css).toHaveBeenCalledWith('background', 'red');
Run Code Online (Sandbox Code Playgroud)

其他想法:我也尝试将间谍对象合并到jQuery中,但这也无济于事.

有任何想法吗?我希望我们不是唯一没有HTML固定装置的人.

che*_*ica 0

找到了。当我的函数版本mock设置为在调用 jQuery 函数时返回 jQuery 对象时,测试有效:

mock (constr, name) {
  var keys = [];
  for (var key in constr.prototype)
    keys.push(key);
  var result = keys.length > 0 ? jasmine.createSpyObj(name || "mock", keys) : {};

  // make sure that if constr is a function (like in the case of jQuery), the mock is too
  if (typeof constr === 'function') {
    var result2 = result;
    result = jasmine.createSpy(name || 'mock-fn');
    result.and.returnValue(result);
    for (var key in result2)
      result[key] = result2[key];
  }
  return result;
}
Run Code Online (Sandbox Code Playgroud)