zz from: http://keenwon.com/1206.html
上一篇把Matcher说了说,本来该说自定义Matcher的,但是发现有些七七八八的细节没讲,那就今天先把这些基础说了。
Setup and Teardown
Setup和Teardown可以帮助Suite执行一些重复的代码,Jasmine提供了beforeEach
和afterEach
函数。很显然,beforeEach
在describe中的任何spec执行之前运行,afterEach
在任何spec执行之后运行。具体的逻辑看Demo就一目了然了:
- describe("Setup和Teardown示例", function() {
- var foo;
- beforeEach(function() {
- foo = 0;
- foo += 1;
- });
- afterEach(function() {
- foo = 0;
- });
- it("测试1", function() {
- expect(foo).toEqual(1);
- });
- it("测试2", function() {
- expect(foo).toEqual(1);
- expect(true).toEqual(true);
- });
- });
前面说过javascript的作用域规则在Jasmine中是适用的,但是这里可以通过this
在beforeEach
,it
,afterEach
中间共享变量。每个spec的this
默认指向空的object。
- describe("this用法示例", function() {
- beforeEach(function() {
- this.foo = 0;
- });
- it("使用this共享状态", function() {
- expect(this.foo).toEqual(0);
- this.bar = "test pollution?";
- });
- it("下个Spec执行前this会被重置为空Object", function() {
- expect(this.foo).toEqual(0);
- expect(this.bar).toBe(undefined);
- });
- });
嵌套describe
可以嵌套使用describe,形成一个Suite树,在一个spec执行之前,Jasmine会顺序执行这颗树上的所有beforeEach
。同样的,执行完spec后,也会顺序执行树上的所有afterEach
- describe("测试嵌套describe:level1", function() {
- var foo;
- beforeEach(function() {
- alert('level1:Setup');
- });
- afterEach(function() {
- alert('level1:Teardown');
- });
- it("level1:测试", function() {
- alert('level1:测试');
- });
- describe("测试嵌套describe:level2", function() {
- beforeEach(function() {
- alert('level2:Setup');
- });
- afterEach(function() {
- alert('level2:Teardown');
- });
- it("level2:测试", function() {
- alert('level2:测试');
- });
- });
- });
具体的执行顺序,点击这里查看上例的效果,你就全明白了。
禁用Suites和挂起Specs
可以使用xdescribe
和xit
函数禁用Suites和specs。当Suites被禁用后,将不显示在报表中。
- 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);
- });
- });
另外可以使用pending
函数将specs挂起,挂起specs和使用xit
函数定义的spec一样,spec不会被执行,但是名字会出现在报表中。另外只有名字,没有实际代码的spec也会在结果中显示为挂起的状态。pending
可以在spec函数体的任何地方调用,不管函数体内有没有expectations,还是看个例子:
- describe("Pending specs", 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();
- });
- });
jasmine.any
jasmine.any
接受构造函数或者“Class”名作为期望值,如果这个构造函数(Class)和实际值的构造函数(Class)匹配,则返回true
。继续看例子:
- 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');
- foo(12, function() {
- return true;
- });
- expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(Function));
- });
- });
- });
jasmine.objectContaining
当一个你只关心实际值是否包含某个键值对的时候,可以使用jasmine.objectContaining
:
- 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
- }));
- });
- });
- });
– 下一篇讲一下自定义Matcher –