Jasmine toEqual用于复杂对象(与函数混合)
目前,我有一个函数,它有时返回一个包含一些函数的对象。使用Jasmine toEqual用于复杂对象(与函数混合),jasmine,matcher,Jasmine,Matcher,目前,我有一个函数,它有时返回一个包含一些函数的对象。使用expect(…).toEqual({…})时,它似乎与那些复杂对象不匹配。对象具有函数或文件类(来自输入类型文件),它就是不能。如何克服此问题?尝试以下功能: expect(_.isEqual(obj1, obj2)).toEqual(true); 如果可行,您可以创建一个: 然后,您可以编写如下规格: expect(some_obj).toDeepEqual(expected_obj); 正如Vlad Magdalin在评论中指出
expect(…).toEqual({…})
时,它似乎与那些复杂对象不匹配。对象具有函数或文件
类(来自输入类型文件),它就是不能。如何克服此问题?尝试以下功能:
expect(_.isEqual(obj1, obj2)).toEqual(true);
如果可行,您可以创建一个:
然后,您可以编写如下规格:
expect(some_obj).toDeepEqual(expected_obj);
正如Vlad Magdalin在评论中指出的那样,将对象设置为JSON字符串,它可以是最深的,函数和文件/文件列表类。当然,它可以被称为“函数”,而不是函数上的
toString()
函数替换器(k,v){
如果(v的类型==='函数'){
v=v.toString();
}else if(窗口['File']&&v文件实例){
v=“[文件]”;
}else if(窗口['FileList']&&v文件列表实例){
v=“[FileList]”;
}
返回v;
}
beforeach(函数(){
这是addMatchers({
toBeJsonEqual:函数(预期){
var one=JSON.stringify(this.actual,replace).replace(/(\\t |\\n)/g',),
two=JSON.stringify(应为replace).replace(/(\\t |\\n)/g');
返回1==2;
}
});
});
expect(obj).toBeJsonEqual(obj2);
如果有人像我一样使用node.js,那么下面的方法就是我在Jasmine测试中使用的方法,我只关心比较简单属性,而忽略所有函数。此方法需要在序列化之前用于对对象属性进行排序的
用法:
var stringify = require('json-stable-stringify');
var obj1 = {
func: function() {
},
str1: 'str1 value',
str2: 'str2 value',
nest1: {
nest2: {
val1:'value 1',
val2:'value 2',
someOtherFunc: function() {
}
}
}
};
var obj2 = {
str2: 'str2 value',
str1: 'str1 value',
func: function() {
},
nest1: {
nest2: {
otherFunc: function() {
},
val2:'value 2',
val1:'value 1'
}
}
};
it('should compare object properties', function () {
expect(stringify(obj1)).toEqual(stringify(obj2));
});
扩展@Vlad Magdalin的答案,这在Jasmine 2中起作用: 如果您正在使用Karma,请将其放入启动回调中:
callback: function() {
// Add custom Jasmine matchers.
beforeEach(function() {
jasmine.addMatchers({
toDeepEqual: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
var result = {};
result.pass = _.isEqual(actual, expected);
return result;
}
}
}
});
});
window.__karma__.start();
});
下面是我如何使用
Jasmine 2
语法完成的
我在。/support/customMatchers.js
中创建了一个customMatchers模块(我喜欢制作模块)
然后在我的测试中使用,如下所示:
"use strict";
let someExternalFunction = require('../../lib/someExternalFunction');
let thingBeingTested = require('../../lib/thingBeingTested');
let customMatchers = require('../support/customMatchers');
describe('myTests', function() {
beforeEach(function() {
jasmine.addMatchers(customMatchers);
let app = {
use: function() {}
};
spyOn(app, 'use');
thingBeingTested(app);
});
it('calls app.use with the correct function', function() {
expect(app.use.calls.count()).toBe(1);
expect(app.use.calls.argsFor(0)).toBeTheSameFunctionAs(someExternalFunction);
});
});
从
toEqual
=>错误中给出相同的结果:预期{异常:函数、数据:函数、代理:函数、远程:函数、追加参数:函数、设置参数:函数、获取参数:函数、删除:函数、生成:函数、取消生成:函数}为深度相等{异常:函数,数据:函数,代理:函数,远程:函数,附加参数:函数,设置参数:函数,获取参数:函数,删除:函数,生成:函数,取消生成:函数}.
您正在比较的对象是否仅由函数组成?在这种情况下,是的,但有时我会使用类以及普通对象和本机包装器,例如文件和文件列表类(JSON.stringify)有效…在你接受修改后我会接受你的答案:)实际上,它不起作用,在检查该函数的输出后,它显示为{}
,这显然是错误的,它似乎无法将函数转换为字符串(如使用(function(){}).toString()
)请注意,JSON.stringify不保证属性顺序!因此比较生成的JSON可能会导致随机测试失败。这取决于底层javascript运行程序如何对属性进行排序。例如:测试可能在engineA(例如NodeJS)中运行,但在engineB(例如Firefox)中中断甚至在另一个engineA版本中。或者在同一版本的同一个引擎中运行时随机均衡。
callback: function() {
// Add custom Jasmine matchers.
beforeEach(function() {
jasmine.addMatchers({
toDeepEqual: function(util, customEqualityTesters) {
return {
compare: function(actual, expected) {
var result = {};
result.pass = _.isEqual(actual, expected);
return result;
}
}
}
});
});
window.__karma__.start();
});
"use strict";
/**
* Custom Jasmine matchers to make unit testing easier.
*/
module.exports = {
// compare two functions.
toBeTheSameFunctionAs: function(util, customEqualityTesters) {
let preProcess = function(func) {
return JSON.stringify(func.toString()).replace(/(\\t|\\n)/g,'');
};
return {
compare: function(actual, expected) {
return {
pass: (preProcess(actual) === preProcess(expected)),
message: 'The functions were not the same'
};
}
};
}
}
"use strict";
let someExternalFunction = require('../../lib/someExternalFunction');
let thingBeingTested = require('../../lib/thingBeingTested');
let customMatchers = require('../support/customMatchers');
describe('myTests', function() {
beforeEach(function() {
jasmine.addMatchers(customMatchers);
let app = {
use: function() {}
};
spyOn(app, 'use');
thingBeingTested(app);
});
it('calls app.use with the correct function', function() {
expect(app.use.calls.count()).toBe(1);
expect(app.use.calls.argsFor(0)).toBeTheSameFunctionAs(someExternalFunction);
});
});