简介
Jasmine 是JavaScript的测试框架,它不依赖其他框架,也不依赖DOM,更重要的是它语法简单。以下实例都是基于Jasmine 2.5.2的,并且来自官网:https://jasmine.github.io/edge/introduction
安装
安装推荐使用npm安装,需要本地和全局安装。
#本地安装
npm install -D jasmine
#全局安装
npm install -g jasmine
#用jasmine初始化项目
jasmine init
#可以生成示例
jasmine examples
#运行测试套件
jasmine
基本组成
Jasmine可以概括为Distribution
、Specs
和Expectations
依次嵌套组成的:
Distribution
对应全局函数describe
,是实现测试套件的开始。describe
接受两个参数:string
和function
。string
是这个测试套件的标题,function
就是实现这个测试套件。可以嵌套多个Distribution
。
Specs
对应全局函数it
,放在describe
的function
参数内,将Distribution
分拆成各个测试规格。it
方法也接受string
和function
,string
是作为这个Specs
的描述,而function
就是放测试期望(Expectations
)。Expectations
可以在it
中存在多个,只要有一个Expectations
是测试不通过的,整个Specs
都是不通过。
Expectations
Expectations
的构建需要使用全局方法expect
,它通过链式Matcher
方法来比较实际值是否和预期值一致,如果一致就是测试通过。
所以Distribution
一般都是这种结构的:
describe("我是describe的string", function() {
var a;
it("我是it的string", function() {
a = true;
expect(a).toBe(true);//可以换成false看下输出什么
});
});
目前Distribution和Specs的作用可以说是将测试套件模块化,不然 “ false expectations “ 描述不通过的时候都不知道找哪里。
Matchers
都是作为Expectations的链式调用而使用,用于比较期望值和实际值。其中可以使用not
进行期望结果的否定。
describe("包括的Matchers:", function() {
it("'toBe' matcher 比较时使用 ===", function() {
var a = 12;
var b = a;
expect(a).toBe(b);
expect(a).not.toBe(null);
});
describe("'toEqual' matcher", function() {
it("适合简单的文本和变量", function() {
var a = 12;
expect(a).toEqual(12);
});
it("也适用于对象的深度比较", function() {
var foo = {
a: 12,
b: 34
};
var bar = {
a: 12,
b: 34
};
expect(foo).toEqual(bar);
});
});
it("'toMatch' matcher 是使用正则表达式", function() {
var message = "foo bar baz";
expect(message).toMatch(/bar/);
expect(message).toMatch("bar");
expect(message).not.toMatch(/quux/);
});
it("'toBeDefined' matcher 是将期望和undefined进行比较", function() {
var a = {
foo: "foo"
};
expect(a.foo).toBeDefined();
expect(a.bar).not.toBeDefined();
});
it("The `toBeUndefined` matcher 是将期望和undefined进行比较", function() {
var a = {
foo: "foo"
};
expect(a.foo).not.toBeUndefined();
expect(a.bar).toBeUndefined();
});
it("'toBeNull' matcher 是将期望和null进行比较", function() {
var a = null;
var foo = "foo";
expect(null).toBeNull();
expect(a).toBeNull();
expect(foo).not.toBeNull();
});
it("'toBeTruthy' matcher 是进行Boolean转换后与true进行比较", function() {
var a, foo = "foo";
expect(foo).toBeTruthy();
expect(a).not.toBeTruthy();
});
it("'toBeFalsy' matcher 是进行Boolean转换后与false进行比较", function() {
var a, foo = "foo";
expect(a).toBeFalsy();
expect(foo).not.toBeFalsy();
});
describe("'toContain' matcher", function() {
it("适用于数组的寻值", function() {
var a = ["foo", "bar", "baz"];
expect(a).toContain("bar");
expect(a).not.toContain("quux");
});
it("也使用于字符串内找单词", function() {
var a = "foo bar baz";
expect(a).toContain("bar");
expect(a).not.toContain("quux");
});
});
it("'toBeLessThan' matcher 进行小于的数值期望比较", function() {
var pi = 3.1415926,
e = 2.78;
expect(e).toBeLessThan(pi);
expect(pi).not.toBeLessThan(e);
});
it("'toBeGreaterThan' matcher 进行大于的数值期望比较", function() {
var pi = 3.1415926,
e = 2.78;
expect(pi).toBeGreaterThan(e);
expect(e).not.toBeGreaterThan(pi);
});
it("'toBeCloseTo' matcher 精确数学比较,没看懂比较结果的依据", function() {
var pi = 3.1415926,
e = 2.78;
expect(pi).not.toBeCloseTo(e, 2);
expect(pi).toBeCloseTo(e, 0);
});
it("'toThrow' matcher 期望函数会抛出异常", function() {
var foo = function() {
return 1 + 2;
};
var bar = function() {
return a + 1;
};
var baz = function() {
throw 'what';
};
expect(foo).not.toThrow();
expect(bar).toThrow();//不抛异常也可以用`toThrow`,不过不能有参数
expect(baz).toThrow('what');//抛new Error()时,这里的参数也需要是new Error()
});
it("'toThrowError' matcher 用于测试特定抛出异常", function() {
var foo = function() {
throw new TypeError("foo bar baz");
};
expect(foo).toThrowError("foo bar baz");
expect(foo).toThrowError(/bar/);
expect(foo).toThrowError(TypeError);
expect(foo).toThrowError(TypeError, "foo bar baz");
});
});
除了使用Matchers进行期望比较外,可以直接使用全局方法fail
否定期望:
describe("使用fail", function() {
var foo = function(x, callBack) {
if (x) {
callBack();
}
};
it("调用fail就是否定这个spec", function() {
foo(false, function() {
fail("Callback has been called");
});
});
});
Setup and Teardown(就是钩子)
有四个全局方法作为钩子的:beforeEach, afterEach, beforeAll, 和 afterAll。
beforeEach和afterEach
beforeEach
/afterEach
会在describe中的每个it的方法参数的调用前/后都会执行一次。粗暴的理解就是说在describe内执行一次或多次,在it内执行一次。
describe("A spec using beforeEach and afterEach", function() {
var foo = 0;
beforeEach(function() {
foo += 1;
});
afterEach(function() {
foo = 0;
});
it("is just a function, so it can contain any code", function() {
expect(foo).toEqual(1);
});
it("can have more than one expectation", function() {
expect(foo).toEqual(1);
expect(true).toEqual(true);
});
});
beforeAll和afterAll
beforeAll
/afterAll
会在describe中的全部it的方法参数的调用前/后只执行一次。粗暴的理解就是说在describe内只执行一次。
describe("A spec using beforeAll and afterAll", function() {
var foo;
beforeAll(function() {
foo = 1;
});
afterAll(function() {
foo = 0;
});
it("sets the initial value of foo before specs run", function() {
expect(foo).toEqual(1);
foo += 1;
});
it("does not reset foo between specs", function() {
expect(foo).toEqual(2);
});
});
this
可以在beforeEach和afterEach的this中定义属性传递it的this。注意这里传递值的时候是值传递,每个it中的this都是相互独立的,改变it中this的属性并不会作用于其他it,也不会影响到beforeEach和afterEach的this:
describe("A spec", function() {
beforeEach(function() {
this.foo = 0;
});
it("can use the `this` to share state", function() {
expect(this.foo).toEqual(0);
this.bar = "test pollution?";
});
it("prevents test pollution by having an empty `this` created for the next spec", function() {
expect(this.foo).toEqual(0);
expect(this.bar).toBe(undefined);
});
});
嵌套describe
describe可以嵌套,并且也说过beforeEach/afterEach会在describe中的每个it的方法参数的调用前/后都会执行一次,所以在嵌套时也会有类似作用域的情况:
describe("A spec", function() {
var foo = 0;
beforeEach(function() {
foo += 1;
});
it("is just a function, so it can contain any code", function() {
expect(foo).toEqual(1);
});
it("can have more than one expectation", function() {
expect(foo).toEqual(2);
expect(true).toEqual(true);
});
describe("nested inside a second describe", function() {
var bar;
beforeEach(function() {
bar = 3;
});
it("can reference both scopes as needed", function() {
expect(foo).toEqual(bar);
});
});
});
Pending
测试套件有时想写上去但是还不用,就要使用xdescribe
方法了,这些套件都会在运行的时候跳过:
xdescribe("A spec", function() {
var foo;
beforeEach(function() {
foo = 0;
foo += 1;
});
it("is just a function, so it can contain any code", function() {
expect(foo).toEqual(1);
});
});
当然也可以只是禁用Specs,那就可以用
-
xit
; -
it
不传递方法参数; - 使用全局的
pending
方法;
describe("A spec", function() {
xit("can be declared 'xit'", function() {
expect(true).toBe(false);
});
it("can be declared with 'it' but without a function");
it("can be declared by calling 'pending' in the spec body", function() {
expect(true).toBe(false);
pending('this is why it is pending');
});
});
Spies
上面的内容可以说就是对值的测试,Jasmine还可以使用spy
对函数的调用情况进行测试。spy
只能在beforeEach、beforeAll或者spec内定义,并且会在各个spec使用后销毁(这个特性很重要)。spy
还有自己的matchers
。分别是:
- toHaveBeenCalled:期望函数被调用;
- toHaveBeenCalledTimes:期望函数的调用次数;
- toHaveBeenCalledWith:期望函数的调用参数;
没有用spyOn
注册的方法是不能使用这些matchers
的。
describe("A spy", function() {
var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar');
foo.setBar(123);
foo.setBar(456, 'another param');
});
it("tracks that the spy was called", function() {
expect(foo.setBar).toHaveBeenCalled();
});
it("tracks that the spy was called x times", function() {
expect(foo.setBar).toHaveBeenCalledTimes(2);
});
it("tracks all the arguments of its calls", function() {
expect(foo.setBar).toHaveBeenCalledWith(123);
expect(foo.setBar).toHaveBeenCalledWith(456, 'another param');
});
it("stops all execution on a function", function() {
expect(bar).toBeNull();
});
});
- 注意:
spyOn
方法的参数必须是(object,methodName)
; - 注意:最后一个spec,
expect(bar).toBeNull();
,明明已经调用了setBar
了,为什么bar还是null的呢?这是因为使用spyOn注册后的方法调用默认都是模拟调用的,并不会执行实际的代码。
and属性的链式操作
spyOn
定义后还可以使用链式操作代理函数的执行。
and.callThrough
函数执行的时候会执行实际的代码。其实除了and.stub
,其他and
属性的方法都会调用and.callThrough
。
describe("A spy, when configured to call through", function() {
var foo, bar, fetchedBar;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
},
getBar: function() {
return bar;
}
};
spyOn(foo, 'getBar').and.callThrough();
foo.setBar(123);
fetchedBar = foo.getBar();
});
it("tracks that the spy was called", function() {
expect(foo.getBar).toHaveBeenCalled();
});
it("should not affect other functions", function() {
expect(bar).toEqual(123);
});
it("when called returns the requested value", function() {
expect(fetchedBar).toEqual(123);
});
});
and.returnValue(value)
注册的方法不会执行代码,而是直接返回and.returnValue
的参数,不过注册对象的其他方法都得到会实际执行。
describe("A spy, when configured to fake a return value", function() {
var foo, bar, fetchedBar ,otherTest;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
},
getBar: function() {
return bar;
}
};
spyOn(foo, "getBar").and.returnValue(745);
foo.setBar(123);
fetchedBar = foo.getBar();
});
it("tracks that the spy was called", function() {
expect(foo.getBar).toHaveBeenCalled();
});
it("should not affect other functions", function() {
expect(bar).toEqual(123);
});
it("when called returns the requested value", function() {
expect(fetchedBar).toEqual(745);
expect(otherTest).toBeUndefined();
});
});
and.returnValues(...value)
和and.returnValue
类似,不过可以接受多个参数,调用函数的时候依次返回这些参数,最后会返回undefined
:
describe("A spy, when configured to fake a series of return values", function() {
var foo, bar;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
},
getBar: function() {
return bar;
}
};
spyOn(foo, "getBar").and.returnValues("fetched first", "fetched second");
foo.setBar(123);
});
it("tracks that the spy was called", function() {
foo.getBar(123);
expect(foo.getBar).toHaveBeenCalled();
});
it("should not affect other functions", function() {
expect(bar).toEqual(123);
});
it("when called multiple times returns the requested values in order", function() {
expect(foo.getBar()).toEqual("fetched first");
expect(foo.getBar()).toEqual("fetched second");
expect(foo.getBar()).toBeUndefined();
});
});
and.callFake(function)
and.returnValue
是直接返回值,and.callFake
就是直接使用一个function代替:
describe("A spy, when configured with an alternate implementation", function() {
var foo, bar, fetchedBar;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
},
getBar: function() {
return bar;
}
};
spyOn(foo, "getBar").and.callFake(function(arguments) {
return 1001;
});
foo.setBar(123);
fetchedBar = foo.getBar();
});
it("tracks that the spy was called", function() {
expect(foo.getBar).toHaveBeenCalled();
});
it("should not affect other functions", function() {
expect(bar).toEqual(123);
});
it("when called returns the requested value", function() {
expect(fetchedBar).toEqual(1001);
});
});
and.throwError(error)
直接让方法抛出异常。
describe("A spy, when configured to throw an error", function() {
var foo, bar;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
},
getBar: function() {
return bar;
}
};
spyOn(foo, "getBar").and.throwError("quux");
foo.setBar(123);
});
it("throws the value", function() {
expect(foo.getBar).toThrowError("quux");
});
it("set bar", function() {
expect(bar).toBe(123);
});
});
and.stub()
去除方法的代理行为。
describe("A spy", function() {
var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar').and.callThrough();
});
it("can call through and then stub in the same spec", function() {
foo.setBar(123);
expect(bar).toEqual(123);
foo.setBar.and.stub();
bar = null;
foo.setBar(123);
expect(bar).toBe(null);
});
});
calls属性
经过spyOn
方法注册后的方法都会有个calls属性跟踪函数使用情况,先定义describe
:
describe("A spy", function() {
var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar');
});
//...all it
});
calls.any()
如果函数没有执行就会返回false
,反之,执行了一次就会返回true
:
it("tracks if it was called at all", function() {
expect(foo.setBar.calls.any()).toEqual(false);
foo.setBar();
expect(foo.setBar.calls.any()).toEqual(true);
});
calls.count()
返回函数的调用次数。
it("tracks the number of times it was called", function() {
expect(foo.setBar.calls.count()).toEqual(0);
foo.setBar();
foo.setBar();
expect(foo.setBar.calls.count()).toEqual(2);
});
calls.argsFor(index)
返回第index次调用时的参数。
it("tracks the arguments of each call", function() {
foo.setBar(123);
foo.setBar(456, "baz");
expect(foo.setBar.calls.argsFor(0)).toEqual([123]);
expect(foo.setBar.calls.argsFor(1)).toEqual([456, "baz"]);
});
calls.allArgs()
返回所有函数调用时的参数。
it("tracks the arguments of all calls", function() {
foo.setBar(123);
foo.setBar(456, "baz");
expect(foo.setBar.calls.allArgs()).toEqual([[123],[456, "baz"]]);
});
calls.all()
返回全部函数调用时的信息,如上下文(this)、参数列表和返回值。如果只有一个就是对象,多个就是数组。
it("has a shortcut to the most recent call", function() {
foo.setBar(123);
foo.setBar(456, "baz");
expect(foo.setBar.calls.mostRecent()).toEqual({object: foo, args: [456, "baz"], returnValue: undefined});
});
calls.mostRecent()/calls.first()
返回最后一次/第一次函数调用时的信息。
it("has a shortcut to the most recent call", function() {
foo.setBar(123);
foo.setBar(456, "baz");
expect(foo.setBar.calls.mostRecent()).toEqual({object: foo, args: [456, "baz"], returnValue: undefined});
expect(foo.setBar.calls.first()).toEqual({object: foo, args: [123], returnValue: undefined});
});
calls.reset()
重置所有的调用信息。
describe("A spy", function() {
var foo, bar = null;
beforeEach(function() {
foo = {
setBar: function(value) {
bar = value;
}
};
spyOn(foo, 'setBar');
});
it("can be reset", function() {
foo.setBar(123);
foo.setBar(456, "baz");
expect(foo.setBar.calls.any()).toBe(true);
foo.setBar.calls.reset();
expect(foo.setBar.calls.any()).toBe(false);
foo.setBar(123);
foo.setBar(456, "baz");
expect(foo.setBar.calls.any()).toBe(true);
});
});
假函数
可以使用createSpy
和createSpyObj
创建假函数,可以时Spies
的全部功能,但是假函数内部并没有可以执行的代码,这种方式经常会用在对JavaScript中的对象的测试。
createSpy
创建一个假函数。
describe("A spy, when created manually", function() {
var whatAmI;
beforeEach(function() {
whatAmI = jasmine.createSpy('whatAmI');
whatAmI("I", "am", "a", "spy");
});
it("is named, which helps in error reporting", function() {
expect(whatAmI.and.identity()).toEqual('whatAmI');
});
it("tracks that the spy was called", function() {
expect(whatAmI).toHaveBeenCalled();
});
it("tracks its number of calls", function() {
expect(whatAmI.calls.count()).toEqual(1);
});
it("tracks all the arguments of its calls", function() {
expect(whatAmI).toHaveBeenCalledWith("I", "am", "a", "spy");
});
it("allows access to the most recent call", function() {
expect(whatAmI.calls.mostRecent().args[0]).toEqual("I");
});
});
createSpyObj
可以通过创建对象,并添加方法的形式创建多个假函数。
describe("Multiple spies, when created manually", function() {
var tape;
beforeEach(function() {
tape = jasmine.createSpyObj('tape', ['play', 'pause', 'stop', 'rewind']);
tape.play();
tape.pause();
tape.rewind(0);
});
it("creates spies for each requested function", function() {
expect(tape.play).toBeDefined();
expect(tape.pause).toBeDefined();
expect(tape.stop).toBeDefined();
expect(tape.rewind).toBeDefined();
});
it("tracks that the spies were called", function() {
expect(tape.play).toHaveBeenCalled();
expect(tape.pause).toHaveBeenCalled();
expect(tape.rewind).toHaveBeenCalled();
expect(tape.stop).not.toHaveBeenCalled();
});
it("tracks all the arguments of its calls", function() {
expect(tape.rewind).toHaveBeenCalledWith(0);
});
});
Matching
值的类型期望。
jasmine.any(constructor)
进行类型检测,可以传入构造函数或在类名。
describe("jasmine.any", function() {
it("matches any value", function() {
expect({}).toEqual(jasmine.any(Object));
expect(12).toEqual(jasmine.any(Number));
});
describe("when used with a spy", function() {
it("is useful for comparing arguments", function() {
var foo = jasmine.createSpy('foo');
class O{};
var o = new O();
foo(12, o , function(){});
expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(O) , jasmine.any(Function));
});
});
});
jasmine.anything()
只要不是null
或在undefined
就可以。
describe("jasmine.anything", function() {
it("matches anything", function() {
expect(null).not.toEqual(jasmine.anything());
expect(undefined).not.toEqual(jasmine.anything());
expect(1).toEqual(jasmine.anything());
});
});
jasmine.objectContaining(object)
期望能找到object中key/value。
describe("jasmine.objectContaining", function() {
var foo;
beforeEach(function() {
foo = {
a: 1,
b: 2,
bar: "baz"
};
});
it("matches objects with the expect key/value pairs", function() {
expect(foo).toEqual(jasmine.objectContaining({
bar: "baz"
}));
expect(foo).not.toEqual(jasmine.objectContaining({
c: 37
}));
});
describe("when used with a spy", function() {
it("is useful for comparing arguments", function() {
var callback = jasmine.createSpy('callback');
callback({
bar: "baz"
});
expect(callback).toHaveBeenCalledWith(jasmine.objectContaining({
bar: "baz"
}));
expect(callback).not.toHaveBeenCalledWith(jasmine.objectContaining({
c: 37
}));
});
});
});
jasmine.arrayContaining(array)
期望array是子数组。
describe("jasmine.arrayContaining", function() {
var foo;
beforeEach(function() {
foo = [1, 2, 3, 4];
});
it("matches arrays with some of the values", function() {
expect(foo).toEqual(jasmine.arrayContaining([3, 1]));
expect(foo).not.toEqual(jasmine.arrayContaining([6]));
});
describe("when used with a spy", function() {
it("is useful when comparing arguments", function() {
var callback = jasmine.createSpy('callback');
callback([1, 2, 3, 4]);
expect(callback).toHaveBeenCalledWith(jasmine.arrayContaining([4, 2, 3]));
expect(callback).not.toHaveBeenCalledWith(jasmine.arrayContaining([5, 2]));
});
});
});
jasmine.stringMatching(string / RegExp)
期望string是子串(不局限于单词),或者RegExp能匹配到。
describe('jasmine.stringMatching', function() {
it("matches as a regexp", function() {
expect({foo: 'bar'}).toEqual({foo: jasmine.stringMatching(/^bar$/)});
expect({foo: 'foobarbaz'}).toEqual({foo: jasmine.stringMatching('bar')});
});
describe("when used with a spy", function() {
it("is useful for comparing arguments", function() {
var callback = jasmine.createSpy('callback');
callback('foobarbaz');
expect(callback).toHaveBeenCalledWith(jasmine.stringMatching('bar'));
expect(callback).not.toHaveBeenCalledWith(jasmine.stringMatching(/^bar$/));
});
});
});
自定义Matching
定义对象的asymmetricMatch方法
就实现了自定义Matching
:
describe("custom asymmetry", function() {
var tester = {
asymmetricMatch: function(actual) {
var secondValue = actual.split(',')[1];
return secondValue === 'bar';
}
};
it("dives in deep", function() {
expect("foo,bar,baz,quux").toEqual(tester);
});
describe("when used with a spy", function() {
it("is useful for comparing arguments", function() {
var callback = jasmine.createSpy('callback');
callback('foo,bar,baz');
expect(callback).toHaveBeenCalledWith(tester);
});
});
});
时间测试
Jasmine Clock可用于测试随时间变化的代码。
在使用前需要调用jasmine.clock().install()
,时间从install
开始进行;在使用完成后,务必调用jasmine.clock().uninstall()
,这样才能再次install
,并且时间才会归0。jasmine.clock().tick(milliseconds)
函数可以让时间前进milliseconds毫秒。
当然了,可以直接使用jasmine.clock().mockDate(baseTime)
将基础时间设置为baseTime
。
describe("Manually ticking the Jasmine Clock", function() {
var timerCallback;
beforeEach(function() {
timerCallback = jasmine.createSpy("timerCallback");
jasmine.clock().install();
});
afterEach(function() {
jasmine.clock().uninstall();
});
it("causes a timeout to be called synchronously", function() {
setTimeout(function() {
timerCallback();
}, 100);
expect(timerCallback).not.toHaveBeenCalled();
jasmine.clock().tick(101);
expect(timerCallback).toHaveBeenCalled();
});
it("causes an interval to be called synchronously", function() {
setInterval(function() {
timerCallback();
}, 100);
expect(timerCallback).not.toHaveBeenCalled();
jasmine.clock().tick(101);
expect(timerCallback.calls.count()).toEqual(1);
jasmine.clock().tick(50);
expect(timerCallback.calls.count()).toEqual(1);
jasmine.clock().tick(50);
expect(timerCallback.calls.count()).toEqual(2);
});
describe("Mocking the Date object", function() {
it("mocks the Date object and sets it to a given time", function() {
var baseTime = new Date(2013, 9, 23);¶
If you do not provide a base time to mockDate it will use the current date.
jasmine.clock().mockDate(baseTime);
jasmine.clock().tick(50);
expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
});
});
});
异步支持
Jasmine还支持异步测试,调用beforeAll, afterAll, beforeEach, afterEach, 和 it
的函数参数时都有个可选参数done
,声明了这个参数后只有调用done
后才会继续以后的代码,所有没有异步操作的时候不要手贱加上去。
异步操作的超时时间默认时5秒,只要5秒内没有done
都会报错,可以给beforeAll, afterAll, beforeEach, afterEach, 和 it
传递一个毫秒作为超时时间。也可以在所有describe
外设置全局的jasmine.DEFAULT_TIMEOUT_INTERVAL
。
describe("Asynchronous specs", function() {
var value;
beforeEach(function(done) {
setTimeout(function() {
value = 0;
done();
}, 1);
});
it("should support async execution of test preparation and expectations", function(done) {
value++;
expect(value).toBeGreaterThan(0);
done();
});
describe("long asynchronous specs", function() {
beforeEach(function(done) {
done();
}, 1000);
it("takes a long time", function(done) {
setTimeout(function() {
done();
}, 9000);
}, 10000);
afterEach(function(done) {
done();
}, 1000);
});
describe("A spec using done.fail", function() {
var foo = function(x, callBack1, callBack2) {
if (x) {
setTimeout(callBack1, 0);
} else {
setTimeout(callBack2, 0);
}
};
it("should not call the second callBack", function(done) {
foo(true,
done,
function() {
done.fail("Second callback has been called");
}
);
});
});
});