Jasmine基础语法
简介
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");
}
);
});
});
});
Jasmine基础语法的更多相关文章
- Swift与C#的基础语法比较
背景: 这两天不小心看了一下Swift的基础语法,感觉既然看了,还是写一下笔记,留个痕迹~ 总体而言,感觉Swift是一种前后端多种语言混合的产物~~~ 做为一名.NET阵营人士,少少多多总喜欢通过对 ...
- iOS-----正则表达式的基础语法
正则表达式简单语法总结 一.什么是正则表达式 从概念上来说,正则表达式也是一门小巧而精炼的语言,它可以用来简化检索特定的字符串,替换特定字符等功能,有许多开发语言工具,都内嵌支持正则表达式.那么一个正 ...
- python之最强王者(2)——python基础语法
背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...
- emmet 系列(1)基础语法
emmet 系列(1)基础语法 emmet 是一个能显著提升开发html和css开发效率的web开发者工具 emmet基本上目前已知的编辑器都有相应的插件,各个编辑器的emmet插件的下载地址:点我下 ...
- Scala基础语法 (一)
如果你之前是一名 Java 程序员,并了解 Java 语言的基础知识,那么你能很快学会 Scala 的基础语法. Scala 与 Java 的最大区别是:Scala 语句末尾的分号 ; 是可选的. 我 ...
- Java基础语法
java基础学习总结——基础语法1 一.标识符
- javascript中正则表达式的基础语法
× 目录 [1]定义 [2]特点 [3]元字符[4]转义字符[5]字符组[6]量词[7]括号[8]选择[9]断言[10]模式[11]优先级[12]局限性 前面的话 正则表达式在人们的印象中可能是一堆无 ...
- Swift基础语法学习总结(转)
Swift基础语法学习总结 1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift使用print和println打印,它的传参是一个泛型 ...
- 黑马程序员——OC语言基础语法 面向对象的思想
Java培训.Android培训.iOS培训..Net培训.期待与您交流! (以下内容是对黑马苹果入学视频的个人知识点总结)(一)基础语法 1)关键字 @interface.@implementati ...
随机推荐
- (简单) UVA 11624 Fire! ,BFS。
Description Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the ow ...
- CentOS6.x升级MySQL版本5.1到5.6
CentOS6.x升级MySQL版本5.1到5.6 分类: Web MySQL 2014-08-04 11:22 2813人阅读 评论(1) 收藏 举报 mysql云服务器升级centos6 有一些虚 ...
- 概率dp初探
论文链接: http://wenku.baidu.com/link?url=vEcfxpqAvGRf6JL9IL2R6v8plBgPnaP3tKp5niOBmoajk0y4CcpwFzL4SkfGS ...
- java学习(三) java 中 mongodb的各种操作
一. 常用查询: 1. 查询一条数据:(多用于保存时判断db中是否已有当前数据,这里 is 精确匹配,模糊匹配 使用 regex...) public PageUrl getByUrl(String ...
- HNU 13064 Cuckoo for Hashing解题报告 North America - East Central 2013
题目大意:使用两个哈希表来解决哈希冲突的问题.假如现在有两个哈希表分别为:H1,H2 ,大小分别为:n1,n2:现有一数据X需要插入,其插入方法为: 1.计算index1 = X MOD N1, 若 ...
- php 禁用eval( )函数
php的eval函数并不是系统组件函数,因此我们在php.ini中使用disable_functions是无法禁止它的. 但是eval()对于php安全来说具有很大的杀伤力,因此一般不用的情况下为了防 ...
- permutation test
- 定制jackson的自定义序列化(null值的处理)
http://www.cnblogs.com/lic309/p/5048631.html
- 第一个shell脚本 结合计划任务下载远程文件
思路: 进入/usr/local/apache2/htdocs/ipa/ 循环读取 /root/shell/wget/down.txt 每次一行,每一行直接就是一条命令,直接 $line 就可以执 ...
- 验证浏览器是否安装已flash插件的js脚本
function flashChecker() { var hasFlash = 0; //是否安装了flash var flashVersion = 0; //flash版本 if(document ...