it-swarm.com.de

Verspottungstermine in AngularJS/Jasmin-Tests

Ich habe eine Direktive, die das Date-Objekt mehrmals in mehreren Funktionen initialisiert. ... Wenn Unit die einzelnen Funktionen testet, kann ich das Stubbing wie folgt behandeln:

(function (global) {
  var NativeDate = global.Date;

  global.stubDateConstructor = function (fakeDate) {
      global.Date = function () {
          global.Date = NativeDate;
          return fakeDate;
      }
  }
}(this));

// ageInYears()
it("should return the age in years of the person given his/her birthdate", function() {
    stubDateConstructor(new Date('2010/01/01'));
    expect(ageInYears('01-01-1990')).toBe(20);
    stubDateConstructor(new Date('2010/01/01'));
    expect(ageInYears('01-01-1900')).toBe(110);
});

Für die Überprüfung der Direktive selbst, die ageInYears und einige andere ähnliche Funktionen aufruft, funktioniert dies nicht, da ich nach einem Aufruf von Date () stubDateConstructor Date () auf das echte Date-Objekt zurückgesetzt habe.

Gibt es in AngularJS/Jasmine eine native Methode, um mit diesen Situationen umzugehen, oder sollte ich beispielsweise Sinon untersuchen?

32
Maarten

Jasmin (2.2) Uhr kann Datum und Uhrzeit nachstellen. 

http://jasmine.github.io/2.2/introduction.html#section-Mocking_the_Date

Zum Beispiel (aus den Dokumenten):

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

Eine einfache Lösung wäre, einen Angular Dates-Dienst zu erstellen, der Date-Objekte für Sie bereitstellt - es könnte sogar nur eine einzige Methode - Dates.now() - vorhanden sein, die das aktuelle Datum durch Rückgabe von new Date() zurücksendet. Sie verwenden diesen Dienst dann, wenn etwas das aktuelle Datum benötigt.

Auf diese Weise können Sie beim Komponententest einen anderen Dates-Dienst hinzufügen, z. B. einen, der beim Aufruf immer ein bestimmtes Datum Ihrer Wahl und nicht die aktuelle Uhrzeit zurückgibt.

12
Dave

angle.mock.TzDate wäre hier eine bessere native Alternative. Dies ist ein Helfer vor Winkelvorgängen und schützt Ihren Test wirklich vor der Zeitzone des Systems oder anderen Abhängigkeiten

https://docs.angularjs.org/api/ngMock/type/angular.mock.TzDate

das spielt gut mit Jasmin oder Mokka

1
prasanth shenoy

Ich konnte mit einer Kombination von sinons falschen Timern die Timers des Fensters und Winkels Mock-Intervall-Service simulieren, um Zeitänderungen zu erkennen. Hier verwendet der zu testende countDownService intern sowohl javscript Date als auch den normalen Intervall-Service von angle Etwas wie:

  describe('when start time was 3000 milliseconds and 1001 milliseconds have passed', function() {
    var startTime;
    var elapse;
    beforeEach(function(){
      this.clock = sinon.useFakeTimers();
      startTime = 3000;
      elapse = 1001;
    });

    var elapseMillis = function(intervalMock,sinonClock,millis){
      sinonClock.tick(millis);
      intervalMock.flush(millis);
    };

    it('elapsedMillis + timeRemainingMillis should == startime', 
      inject(function($rootScope,$interval,countdownService) {
        countdownService.startTimer(startTime);
        elapseMillis($interval,this.clock,elapse);
        //jasmine clock does not mock Date
        //see https://github.com/pivotal/jasmine/issues/361
        var elapsedMillis = countdownService.getElapsedMillis();
        var timeRemainingMillis = countdownService.getTimeRemainingMillis();
        expect(elapsedMillis + timeRemainingMillis).toEqual(startTime);
        expect(elapsedMillis).toEqual(elapse);
    }));

    afterEach(function(){
      this.clock.restore();
        startTime = 0;
        elapse = 0;
    });
  });

Sie sollten sicherstellen, dass der Code sinon-timers-1.8.1.js von sinon js auch in Ihre karma.conf.js files -Eigenschaft aufgenommen wird.

0
ossek