angular2单元测试

1、Jasmine  之 Spies

代码示例:

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();
    });
    it("tracks if it was called at all", function() {
        foo.setBar();

        expect(foo.setBar.calls.any()).toEqual(true);
    });
});

示例代码讲解:

Jasmine 有双重功能,即间谍 (spies) (spy)

spy可以存根任何函数,并跟踪调用他的所有参数。

spy只存在于定义他的 describe 或 it 块中,并且在每个 it (spec 规范)之后将被删除。

spy有自己特定的匹配器,用来断言(expect)。

断言匹配器:

  toHaveBeenCalled:判断spy是否被调用过,被调用过即断言通过。

  toHaveBeenCalledTimes(次数):方法参数为数字,即断言当前spy是否被调用过几次

  toHaveBeenCalledWith():方法接收一个参数,即断言当前spy是否使用用当前参数调用过

  calls():追踪spy被调用过的所有的参数

2、createSpy

代码示例:

describe("A spy, when created manually", function() {
  var whatAmI;

  beforeEach(function() {
    whatAmI = jasmine.createSpy('whatAmI');

    whatAmI("I", "am", "a", "spy");
  });

  it("tracks that the spy was called", function() {
    expect(whatAmI).toHaveBeenCalled();
  });
});

示例代码讲解:

当没有可以spyon的功能对象或者方法时,可以通过 jasmine.createSpy() 创建一个空的spy。

这个spy可以充当任何其他spy被调用,追踪。但是他没有实例。

3、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();
  });
});

示例代码讲解:

使用 jasmine.createSpyObj() 有序的创建一个具有多个spy的mock(模拟),

jasmine.createSpyObj('名称', ['spy1', 'spy2'])

参数:

  参数一:名称 

  参数二:字符串数组

返回一个对象,参数数组中的每一项即为对象的属性,也是spy。

4、一些巧妙的匹配器

4.1 jasmine.any()

代码示例:

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.any():方法接收数据类型作为参数,断言实际值是否是期望数据类型

4.2 jasmine.anything()

代码示例:

describe("jasmine.anything", function() {
    it("matches anything", function() {
      expect(1).toEqual(jasmine.anything());
    });

    describe("when used with a spy", function() {
      it("is useful when the argument can be ignored", function() {
        var foo = jasmine.createSpy('foo');
        foo(12, function() {
          return false;
        });

        expect(foo).toHaveBeenCalledWith(12, jasmine.anything());
      });
    });
  });

示例代码讲解:

jasmine.anything():断言实际值是否不是null或者未定义,如果不是null或者未定义,即返回 true

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

示例代码讲解:

jasmine.objectContaining():接收一个对象参数,用于断言实际值为对象的,且对象是否包含参数对象中的键值对

4.4 jasmine.arrayContaining

代码示例:

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.arrayContaining():接收一个数组参数,用于断言实际值为数组,且数组是否包含参数数组中的项

4.5 jasmine.stringMatching

代码示例:

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

示例代码讲解:

jasmine.stringMatching():接收字符串或者正则表达式为参数,

用于不希望精确地匹配较大对象中的字符串时,或者匹配spy中的一部分字符串(此处说法较为复杂难解,直接参考代码即可理解)

4.6 自定义检测器

代码示例:

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

示例代码讲解:

当我们需要断言某变量是否符合特定条件时,可以通过自定义一个具有 asymmetricMatch 函数作为其属性的对象,来指定一个定制的测试器。

5、jasmine Clock

代码示例:

describe("Manually ticking the Jasmine Clock", function() {
    var timerCallback;
    beforeEach(function() {
        timerCallback = jasmine.createSpy("timerCallback");
        jasmine.clock().install();
    });
    afterEach(function() {
        jasmine.clock().uninstall();
    });
    it("模拟js的超时函数", 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);
            jasmine.clock().mockDate(baseTime);

            jasmine.clock().tick(50);
            expect(new Date().getTime()).toEqual(baseTime.getTime() + 50);
        });
    });
});

示例代码讲解:

Jasmine Clock 用于测试与时间相关的代码。

jasmine.clock().install():在需要操作时间的 describe 或者 it 中,安装时间控件才能进行时间相关操作

jasmine.clock().uninstall():在不需要操作时间后,一定要卸载时间控件。

jasmine.clock().tick():接收毫秒为单位的时间,实现时间后推移

jasmine.clock().mockDate():接收时间参数(时间戳),如果不传参数,默认为当前时间,用来模拟当前时间

原文地址:https://www.cnblogs.com/jing5990/p/12761552.html