作者:zccst
单测,在前端,对于我而言,还是第一次。得好好学学单测了。
看看介绍,慢慢来。
参考:
官方文档:
http://jasmine.github.io/2.0/introduction.html
https://gist.github.com/OakRaven/2623232
断断续续看了两次,基本看懂了,下面是一些基础的用法,高级用法另写一篇吧
describe("Player", function() {
var player;
var song;
beforeEach(function() {
player = new Player();
song = new Song();
});
it("should be able to play a Song", function() {
player.play(song);
expect(player.currentlyPlayingSong).toEqual(song);
//demonstrates use of custom matcher
expect(player).toBePlaying(song);
});
describe("when song has been paused", function() {
beforeEach(function() {
player.play(song);
player.pause();
});
it("should indicate that the song is currently paused", function() {
expect(player.isPlaying).toBeFalsy();
// demonstrates use of 'not' with a custom matcher
expect(player).not.toBePlaying(song);
});
it("should be possible to resume", function() {
player.resume();
expect(player.isPlaying).toBeTruthy();
expect(player.currentlyPlayingSong).toEqual(song);
});
});
// demonstrates use of spies to intercept and test method calls
it("tells the current song if the user has made it a favorite", function() {
spyOn(song, 'persistFavoriteStatus');
player.play(song);
player.makeFavorite();
expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
});
//demonstrates use of expected exceptions
describe("#resume", function() {
it("should throw an exception if song is already playing", function() {
player.play(song);
expect(function() {
player.resume();
}).toThrowError("song is already playing");
});
});
/**/
describe("The 'toEqual' matcher", function() {
//测toBe
it("The 'toBe' matcher compares with ===", function() {
var a = 12;
var b = a;
expect(a).toBe(b);
expect(a).not.toBe(null);
});
//测toEqual
it("works for simple literals and variables", function() {
var a = 12;
expect(a).toEqual(12);
});
it("should work for objects", function() {
var foo = {
a: 12,
b: 34
};
var bar = {
a: 12,
b: 34
};
expect(foo).toEqual(bar);
});
//测toMatch
it("The 'toMatch' matcher is for regular expressions", function() {
var message = "foo bar baz";
expect(message).toMatch(/bar/);
expect(message).toMatch("bar");
expect(message).not.toMatch(/quux/);
});
//测toBeDefined
it("The 'toBeDefined' matcher compares against `undefined`", function() {
var a = {
foo: "foo"
};
expect(a.foo).toBeDefined();
expect(a.bar).not.toBeDefined();
});
//测`toBeUndefined`
it("The `toBeUndefined` matcher compares against `undefined`", function() {
var a = {
foo: "foo"
};
expect(a.foo).not.toBeUndefined();
expect(a.bar).toBeUndefined();
});
//测toBeNull
it("The 'toBeNull' matcher compares against null", function() {
var a = null;
var foo = "foo";
expect(null).toBeNull();
expect(a).toBeNull();
expect(foo).not.toBeNull();
});
//测toBeTruthy
it("The 'toBeTruthy' matcher is for boolean casting testing", function() {
var a, foo = "foo";
expect(foo).toBeTruthy();
expect(a).not.toBeTruthy();
});
//测toBeFalsy
it("The 'toBeFalsy' matcher is for boolean casting testing", function() {
var a, foo = "foo";
expect(a).toBeFalsy();
expect(foo).not.toBeFalsy();
});
//测toContain(针对数组)
it("The 'toContain' matcher is for finding an item in an Array", function() {
var a = ["foo", "bar", "baz"];
expect(a).toContain("bar");
expect(a).not.toContain("quux");
});
//测toBeLessThan
it("The 'toBeLessThan' matcher is for mathematical comparisons", function() {
var pi = 3.1415926,
e = 2.78;
expect(e).toBeLessThan(pi);
expect(pi).not.toBeLessThan(e);
});
//测toBeGreaterThan
it("The 'toBeGreaterThan' matcher is for mathematical comparisons", function() {
var pi = 3.1415926,
e = 2.78;
expect(pi).toBeGreaterThan(e);
expect(e).not.toBeGreaterThan(pi);
});
//测toBeCloseTo,第二个参数比较费解,看源码后知道是10的x次方,然后四舍五入
it("The 'toBeCloseTo' matcher is for precision math comparison", function() {
var pi = 3.1415926,
e = 2.78;
expect(pi).not.toBeCloseTo(e, 2);//乘以10的2次方,扩大100倍,然后四舍五入
expect(pi).toBeCloseTo(e, 0);//乘以10的0次方,扩大1倍,然后四舍五入
});
//测toThrow
it("The 'toThrow' matcher is for testing if a function throws an exception", function() {
var foo = function() {
return 1 + 2;
};
var bar = function() {
return a + 1;
};
expect(foo).not.toThrow();
expect(bar).toThrow();
});
});
//The this keyword
describe("A spec", function() {
var bar1;
//beforeEach,afterEach里可以设置this.xx变量,而且在全部it里有效
beforeEach(function() {
this.foo = 0;
bar1 = "hello";//有效
});
//但是一个it里的this.xx变量,在另一个it里无效
it("can use the `this` to share state", function() {
expect(this.foo).toEqual(0);
this.bar = "test pollution?";
//bar1 = "hello";//无效
});
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);//true,未被另一个it污染
expect(bar1).toBe("hello");
});
});
//嵌套
describe("A spec", function() {
var foo;
beforeEach(function() {
foo = 0;
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);
});
//先执行内部describe,再执行外部的afterEach
//外部的变量,可以在内部describe访问
describe("nested inside a second describe", function() {
var bar;
beforeEach(function() {
bar = 1;
});
it("can reference both scopes as needed", function() {
expect(foo).toEqual(bar);
});
});
});
//对于describe,直接改成xdescribe即可
//悬而未决,挂起 运行后,点击显示是*号。
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();
});
});
});