Jasmine基础API

本文详细介绍了如何使用Jasmine进行单元测试,包括基本使用方法、API使用、Matcher、手动失败、设置与清理、禁用套件、挂起方法、间谍方法等功能的运用,以及如何在测试中实现时间模拟和异步支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. Jasmine官网documen地址 http://jasmine.github.io/2.4/introduction.html

  2. 简单使用:去github上下载最新的Release的zip包,本地解压后打开:SpecRunner.html(运行文件)、src(js源文件夹)、spec(js测试文件夹)、lib(jasmine依赖的js库)

  3. 打开SpecRunner.html文件,在注释说明的相应位置添加源文件、测试文件。

    <!DOCTYPE html>
    <html>
    <head>
      <meta charset="utf-8">
      <title>Jasmine Spec Runner v2.3.4</title>
    
      <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.3.4/jasmine_favicon.png">
      <link rel="stylesheet" href="lib/jasmine-2.3.4/jasmine.css">
    
      <script src="lib/jasmine-2.3.4/jasmine.js"></script>
      <script src="lib/jasmine-2.3.4/jasmine-html.js"></script>
      <script src="lib/jasmine-2.3.4/boot.js"></script>
    
      <!-- include source files here... -->
      <script src="src/Player.js"></script>
      <script src="src/Song.js"></script>
    
      <!-- include spec files here... -->
      <script src="spec/SpecHelper.js"></script>
      <script src="spec/PlayerSpec.js"></script>
    
    </head>
    <body>
    </body>
    </html>
  4. spec.js文件基本格式

    describe("A suite is just a function", function() {
      var a;
    
      it("and so is a spec", function() {
        a = true;
    
        expect(a).toBe(true);
      });});

    describe\it都是function,describe用来定义spec suite,it用来定义spec。

    第一个参数都为字符串,第二个为测试块。

    describe:“The string is a name or title for a spec suite – usually what is being tested. The function is a block of code that implements the suite.

    it:“The string is the title of the spec and the function is the spec, or test. A spec contains one or more expectations that test the state of the code. An expectation in Jasmine is an assertion that is either true or false. 

  5. 基础API的使用

    Matcher

expect().toBe();            //同===
expect().not.toBe();        //所有的断言都可用not取反
expect().toEqual();         //可比较字面量或者变量指向的对象内容
expect().toMatch(/bar/);    //正则
expect().toBeDefined();     //是否被定义,未定义是undefined
expect().toBeUndefined();   //是否未定义
expect().toBeNull();        //是否是null
expect().toBeTruthy();      //是否为truthy
expect().toBeFalsy();       //是否未falsy
expect().toContain();       //数组是否包含某元素,基与equals对比
expect().toBeLessThan();    //小于某值, 可比较数字、字符串、时间
expect().toBeGreaterThan(); //大于某值
expect().toBeCloseTo(, 0);  //根据第二位参数所给的精度,保留相应精度,其后“Round_half_down”,比较值是否相等
expect(fn1).toThrow();     //断言fn1运行会抛出异常

//断言fn1运行会抛出具体异常
expect(fn1).toThrowError("foo bar baz");    
expect(fn1).toThrowError(/bar/);
expect(fn1).toThrowError(TypeError);
expect(fn1).toThrowError(TypeError, "foo bar baz");

手动失败

fail("Callback has been called");

Setup and Teardown

beforeEach, afterEach, beforeAll, afterAll

在嵌套describe的情况,在it之前会按照由外靠内的顺序执行beforeEach,结束后又由内到外执行afterEach。

this

在一个spec的beforeEach/it/afterEach范围内有效分享对象的方式。

Each spec’sbeforeEach/it/afterEach has the this as the same empty object that is set back to empty for the next spec’s beforeEach/it/afterEach.

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);
  });});

Disabling Suites:

xdescribe("A spec", function() {});

Pending Specs:

Pending specs do not run, but their names will show up in the results aspending”。且方法内的一切断言将被忽视。

//三种方式
xit("can be declared 'xit'", function() {
    expect(true).toBe(false);
  });
  
it("can be declared with 'it' but without a function");

//该方法内部调用了pending,将标记为pending方法,参数传达pending原因。
it("can be declared by calling 'pending' in the spec body", function() {
    expect(true).toBe(false);
    pending('this is why it is pending');
  });

Spies:

 A spy can stub any function and tracks calls to it and all arguments. 

spyOn(foo, 'setBar');                        //创建spy,并拦截对方法的调用
spyOn(foo, 'getBar').and.callThrough();      //创建spy,并代理真实方法的调用

//创建spy,并拦截结果的返回,给予结果定义。所有的返回结果被替换。
spyOn(foo, "getBar").and.returnValue(745);   
//创建spy,并拦截结果的返回,按照调用顺序给予结果定义
spyOn(foo, "getBar").and.returnValues("fetched first", "fetched second"); 

//fake一个方法
spyOn(foo, "getBar").and.callFake(function() {
      return 1001;
    });
        
spyOn(foo, "setBar").and.throwError("quux");  //所有的调用将抛出异常

//and.stub(),fake一个空方法体
spyOn(foo, 'setBar');
foo.setBar.and.stub();

jasmine.createSpy

whatAmI = jasmine.createSpy('whatAmI');    //创建一个方法用于spy,不需要该方法已经定义, context为定义时的上下文
tape = jasmine.createSpyObj(['play', 'pause', 'stop', 'rewind']);    //创建一个对象,且属性也同时被定义

matcher:

expect(foo.setBar).toHaveBeenCalled();            //已经被调用
expect(foo.setBar).toHaveBeenCalledWith(123);     //已经通过参数XX调用

//======期望值的matcher======
expect(foo).toHaveBeenCalledWith(jasmine.any(Number), jasmine.any(Function));    //jasmine.any(构造函数名),此类型的任何对象即可匹配
expect(foo).toHaveBeenCalledWith(12, jasmine.anything());                        //jasmine.anything(),非undefined\null的即可匹配
expect(foo).toEqual(jasmine.objectContaining({bar: "baz"}));                     //jasmine.objectContaining,包含此属性的对象即可匹配
expect(foo).toEqual(jasmine.arrayContaining([3, 1]));                            //jasmine.arrayContaining,包含其元素子集的数组即可匹配
expect({foo: 'bar'}).toEqual({foo: jasmine.stringMatching(/^bar$/)});            //jasmine.stringMatching,包含此字符串匹配方式的即可匹配(参数方式可参见toMatch)

//自定义任何想要的期望匹配:asymmetricMatch
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);
    });
  });});

spy.calls:

Every call to a spy is tracked and exposed on the calls property.” 对spy的完整track信息。

expect(foo.setBar.calls.any()).toEqual(false); //spy的函数被调用至少一次,则返回true
expect(foo.setBar.calls.count()).toEqual(0);   //spy的函数被调用的次数

//函数被调用的索引对应的参数列表:foo.setBar.calls.argsFor
foo.setBar(123);
foo.setBar(456, "baz");
expect(foo.setBar.calls.argsFor(0)).toEqual([123]);
expect(foo.setBar.calls.argsFor(1)).toEqual([456, "baz"]);
//被调用的历史完整列表:foo.setBar.calls.allArgs
expect(foo.setBar.calls.allArgs()).toEqual([[123],[456, "baz"]]);

//track的历史所有完整信息:foo.setBar.calls.all(注意是数组)
expect(foo.setBar.calls.all()).toEqual([{object: foo, args: [123], returnValue: undefined}]);

//track的最近一次的完整信息:foo.setBar.calls.mostRecent
expect(foo.setBar.calls.mostRecent()).toEqual({object: foo, args: [456, "baz"], returnValue: undefined});

//track的第一次的完整信息:foo.setBar.calls.first
expect(foo.setBar.calls.first()).toEqual({object: foo, args: [123], returnValue: undefined});

expect(spy.calls.first().object).toBe(foo);    //object为调用上下文context
foo.setBar.calls.reset();                      //清除track历史记录,重置

Jasmine Clock

beforeEach中jasmine.clock().install();
afterEach中jasmine.clock().uninstall();
it中使用jasmine.clock().tick(101); 调用时模拟时间已经走了101毫秒,好似时间加速器

//模拟绝对时间
var baseTime = new Date(2013, 9, 23);
jasmine.clock().mockDate(baseTime);
jasmine.clock().tick(50);
expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);

Asynchronous Support:done

可使用在beforeEach/it/afterEach中,function注入done即可。注入done声明此处有异步调用,测试需要等待。

如在“jasmine.DEFAULT_TIMEOUT_INTERVAL”超时之前都未有调用done方法,其后将失败。可通过beforeEach/afterEach的第二个参数,it的第三个参数声明超时时间。

it("takes a long time", function(done) {
            setTimeout(function() {
                done();
            }, 9000);
        }, 10000);


转载于:https://my.oschina.net/elleneye/blog/546521

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值