最好的方法(海事组织):
test.add("Expect job not to be done.", function(expect){
expect(job.done).toBe(false);
})
此问题已更新,如果有人可能需要,我将在此处发布如何完成测试。
下面的原始问题...
我知道这甚至不可能,但我会清楚地解释我为什么以及如何让它工作:
为什么?
我想做一些在缺少某些东西时不会失败的测试,并且我不想测试所有东西是否存在。
例子:
expect('Something', existingClosureVar.notExistingProperty.toString()).toBe('ho ho');
这将引发如下错误:TypeError: Cannot call method 'toString' of undefined。
解决这个问题很容易,但也很痛苦!
if(existingClosureVar && existingClosureVar.notExistingProperty && existingClosureVar.notExistingProperty.toString){
expect('Something', existingClosureVar.notExistingProperty.toString()).toBe('ho ho');
}
好吧,但如果它不存在,我什至不会注意到失败的测试!也许可能存在一些更详细的解决方法,但会使这段代码越来越大,而我想要的只是一个简单的东西,这应该是尽可能短的东西。
应该如何工作?
expect('Something', 'existingClosureVar.notExistingProperty.toString()').toBe('ho ho');
不知何故,expect 函数应该可以访问闭包的局部变量以使其工作。它将在 try-catch 上下文中运行字符串,如果失败,测试也会失败。
我想要的确切的东西:
var callingFn = function(){
var a = 99;
// remember, the eval can't sit here, must be outside
var evalString = 'console.log(a)'; // should print 99
expect(this, evalString); //
}
var expect = function(context, evalString){
var fn = function(){
eval(evalString)
}
fn.call(context);
}
new callingFn(); // creates a this in the callingFn that is not the window object
如果我提供上下文,它会起作用,但是......
那将要求我使用“这个”。符号来获取变量。由于很多函数是异步的,并且函数的上下文没有维护(可以维护,但需要做更多的工作)(或者我们可以使用闭包变量来保留上下文变量)。
例子:
var callingFn = function(){
var context = {b: 1};
var evalString = 'b'; // prints 1
expect(context, evalString)
}
var expect = function(context, evalString){
var fn = function(){
console.log(eval('this.' + evalString))
}
fn.call(context);
}
callingFn()
我发现了一个丑陋的解决方案:
var callingFn = function(){
// setup the context
var context = {};
// give access to the local closure
context.fn = function(evalString){
console.log(eval(evalString))
}
var a = 99;
var evalString = 'a'; // should print 99
expect(context, evalString);
}
var expect = function(context, evalString){
context.fn(evalString);
}
callingFn()
可行的解决方案,但仍然过于冗长:
而且我必须在代码前放 4 行,但这里是Click here to open the Fiddle example:
var callingFn = function(expect){
// give access to the local closure
expect.fn = function(evalString){
try {return [undefined, eval(evalString)];
}catch(e){return [e, undefined];}
}
var a = {hey: 1, b: {c: 99}};
console.log(expect('a.b.c', 99)); // true
console.log(expect('a.b.c.d.f', 99)); // return the error
console.log(expect('a.b.c', 44)); // false
console.log(expect('a.hey', 1)); // true
}
var expect = function(evalString, target){
var result = expect.fn(evalString);
var err = result[0];
var output = result[1];
if(err){
return err.stack;
}else{
return output === target;
}
}
callingFn(expect)
共享上下文:
var callingFn = function(expect){
// give access to the local closure
var context = {};
expect.context = context;
context.a = {hey: 1, b: {c: 99}};
console.log(expect('a.b.c', 99)); // true
console.log(expect('a.b.c.d.f', 99)); // return the error
console.log(expect('a.b.c', 44)); // false
console.log(expect('a.hey', 1)); // true
}
var expect = function(evalString, target){
var fn = function(evalString){
try {return [undefined, eval('this.' + evalString)];
}catch(e){return [e, undefined];}
}
var result = fn.call(expect.context, evalString);
var err = result[0];
var output = result[1];
if(err){
return err.stack;
}else{
return output === target;
}
}
callingFn(expect)
本地变量 + 字符串:
var callingFn = function(expect){
// give access to the local closure
var a = {hey: 1, b: {c: 99}};
console.log(expect(a, '.b.c', 99)); // true
console.log(expect(a, '.b.c.d.f', 99)); // return the error
console.log(expect(a, '.b.c', 44)); // false
console.log(expect(a, '.hey', 1)); // true
}
var expect = function(object, evalString, target){
var fn = function(evalString){
try {return [undefined, eval('object' + evalString)];
}catch(e){return [e, undefined];}
}
var result = fn(evalString);
var err = result[0];
var output = result[1];
if(err){
return err.stack;
}else{
return output === target;
}
}
callingFn(expect)
// 示例适用于谷歌浏览器,它可能不适用于其他浏览器。