我正在创建一个使用Jasmine测试Angular过滤器的函数。规格由Karma运行。我们的想法是传递一个模块和过滤器名称,并在其上执行一系列测试。该数组的每个元素都有描述,输入值和预期结果。但它也可以包含testSteps函数,用于测试,这些测试不像传递输入值那样简单并且期望精确值。我正在创建的函数是为了创建相应的Jasmine描述并阻止测试,它在一个定义如下的全局变量中:
#include <stdio.h>
void capitalize(char *str)
{
char *p = str;
while(*p++) {
if (*p >= 97 && *p <= 122) {
*p -= 32;
}
}
}
void strCopy(char *str2, char *str1)
{
while (*str2) {
*str1 = *str2;
str2++;
str1++;
}
*str1 = '\0';
}
int main(int argc, char **argv)
{
char string1[100] = "This is a really long string!";
char string2[100];
strCopy(string1, string2);
capitalize(string2);
printf("The original string is \"%s\"\n", string1);
printf("The capitalized string is \"%s\"\n", string2);
}
我的测试代码是:
var $uite = {
testFilter : function(filterName, moduleName, tests) {
this.filterObject = null;
this.isDefined = function(vble) {
return typeof (vble) != 'undefined';
}
describe('FILTER: ' + filterName, function() {
beforeEach(module(moduleName));
beforeEach(inject(function($filter) {
filterObject = $filter(filterName);
}));
for (var i = 0; i < tests.length; i++) {
var test = tests[i];
it(test.it, function() {
if (typeof (test.forInputValue) != 'undefined') {
var result = filterObject(test.forInputValue);
expect(result).toEqual(test.resultShouldBe);
} else if (typeof (test.testSteps) != 'undefined') {
test.testSteps();
}
});
}
});
}
}
它工作得很好,但仅仅是为了好奇,因为我避免创建不必要的全局变量,我在它们之后编写了以下测试:
$uite.testFilter('nameFilter', 'app', [ {
it : 'gets male gender from a name ending in O',
forInputValue : 'Pedro',
resultShouldBe : 'el tal Pedro'
}, {
it : 'gets female gender from a name ending in A',
forInputValue : 'Carolina',
resultShouldBe : 'la tal Carolina'
}, {
it : 'transforms Lina into la tal Lina',
testSteps : function() {
var result = filterObject('Lina');
expect(result).toEqual('la tal Lina');
}
} ]);
由于filterObject的类型是函数,因此失败。如果我的filterObject是在$ uite对象中定义的并且不是(是吗?)隐式声明的,那么为什么它可以从另一个describe / it块集中访问?
答案 0 :(得分:1)
您的问题:我是否在创建全局变量?
是
这是全球性的。你在这里做全球化:
filterObject = $filter(filterName);
如果你之前没有放置var
,并且你没有使用严格模式(例如use strict;
),那么它将是全局的。
如果您想要引用this
,则需要在任何地方使用this
:
beforeEach(inject.call(this, function($filter) {
this.filterObject = $filter(filterName);
}.bind(this)));
或类似的东西。或者,您可以声明var _this = this
:
beforeEach(inject(function($filter) {
_this.filterObject = $filter(filterName);
}));
在整个代码中的其他任何位置,您都需要将其称为this.filterObject
。
仅供参考,有关strict mode (article on MDN)的说明(我总是建议使用它,因为它会捕获意外的全局变量),请参阅“将错误转换为错误”部分:
首先,严格模式使得无法意外地创建全局变量。
其他参考资料:
P.S。看起来你是来自Java背景。使用对象时,定义this.<whatever>
然后尝试将其简称为<whatever>
将无法在JavaScript中使用,就像您期望它在Java中一样。
要在第三次测试中访问filterObject
,请执行以下操作:
// ... in $suite
} else if (typeof (test.testSteps) != 'undefined') {
// make this.filterObject available as a parameter
test.testSteps(this.filterObject);
}
// then in your test definition...
}, {
it : 'transforms Lina into la tal Lina',
testSteps : function(filterObject) { // this line is important
var result = filterObject('Lina');
expect(result).toEqual('la tal Lina');
}
} ]);