2013-06-13 8 views
27

Dateオブジェクトをいくつかの関数で何度も初期化する指示があります。 私はこのような日付をスタブ扱うことができ、個々の機能テスト単位:ageInYearsや他のいくつかの類似の機能を呼び出すディレクティブ自体を単体テストするためにAngularJS/Jasmineテストの締め日

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

が、これは1つの呼び出した後、私と仕事に行くのではありませんto Date()stubDateConstructorはDate()を実際のDateオブジェクトにリセットします。

AngularJS/Jasmineには、これらの状況を処理するためのネイティブな方法がありますか?たとえばSinonを調べる必要がありますか?

+0

とよく果たしているシステムのタイムゾーンまたは任意の他の依存関係

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

からの角度モックからヘルパー、本当に安全ガードあなたのテストとして来ます日付を一度初期化し、それを必要とする関数に渡すことができます。これが最善の解決策ですか? – Maarten

+0

私はTimecop.jsのファンです。 Timecop.travelやTimecop.freezeのような関数を持つライブラリは私の承認を得ます。 – ivarni

+0

sinon.jsのように見えるかもしれませんが、日付に適用されるタイムモッキングを提供する可能性があります(ブラウザのサポートに依存します)http://sinonjs.org/docs/#clock – ossek

答えて

50

ジャスミン(2.2)時計は日時を模擬することができます。

例えば

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

(ドキュメントから):

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

ありがとう、私は尋ねたときに戻って存在しなかったように見えるが、今すぐ正しいツールに見える – Maarten

12

簡単な解決策は、あなたのためDateオブジェクトを提供アンギュラDatesサービスを作成することです - Dates.now() - - ちょうどnew Date()を返すことによって、現在の日付を送り返すことを言ってもただ一つの方法があるかもしれません。このサービスは、何か現在の日付を取得する必要があるときはいつでも使用します。

これにより、ユニットテスト時に別のDatesサービスを注入することができます。たとえば、現在の時刻ではなく、呼び出されたときにいつも選択した特定の日付を返します。

+0

シンプルなので、私の心はあらゆる種類のばかげた複雑なシナリオ。ありがとう兄貴! – rooftop

0

私はsinon's fake timersの組み合わせを使ってモックして、ウィンドウのタイマーと角度の角度mock interval serviceをモックして時間の変化を認識することができました。あまりにも、あなたのkarma.conf.jsにsinon JSのsinon-timers-1.8.1.jsを確認すると、含まれます

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

プロパティをファイル:ここでは、テスト対象のcountDownServiceは両方javscript Dateなどの角度、通常interval service何かの内部で使用します。

1

angular.mock.TzDateここより良いネイティブの選択肢だろう。これは、これはそれが、今私が持っているかもしれないと私に明けだジャスミンやモカ

関連する問題