2016-01-15 36 views
0

構建沒有立即結果的代碼測試的方法是什麼?如何爲隨時間發生的過程構建測試?

比方說,我們有一個非常簡單的(但很粗魯)過程:

  • 用戶註冊到網站
  • 兩天通過
    • 發送提醒郵件
    • 更新一些數據庫字段
  • 十天過關
    • 發送 「c'ya」 電子郵件
    • 刪除帳戶

我可以寫每一組子任務測試(發送電子郵件,數據庫更新等)。但是我怎麼寫的結構良好的測試,該讀的東西,如:

「報名兩天後,提醒郵件應該發送」 「註冊後10天,賬戶被刪除」

雖然我使用PHP和PHPUnit,我覺得這個問題可能/不可能是語言不可知的。

回答

1

基於您的事件機制的實施。由手動發送該事件

1)測試提醒,發送腳本:像,當你的代碼中的一些事件偵聽器的地方接收事件user:reminder使用用戶ID,那麼你只需要

$eventBus->init(); 
$eventBus->attachListener($reminderListener); 

$eventBus->fire(new ReminderEvent($user->id)); 

$this->expect(...); // reminder must be `sent` 

2)測試生成事件的時候時間已經過去了:

$time = now(); 
$delay = ...; 

$emitter = new RemindEventEmitter($user->id, $time + $delay) 

$eventBus->addEmitter($emitter); 

$eventBus->setCurrentTime($time); // when we just registered emitter... 
$eventBus->run(); 

$this->expectNot(...); // ... that event _must not_ be fired 

$eventBus->setCurrentTime($time + $delay); // manually skip $delay time ... 
$eventBus->run(); 

$this->expect(...); // test that event _must_ be fired 

這事件產卵/(在我的例子$eventBus)分派的事情必須在中繼mockable /更換的時間拼命三郎:

// in production code 
$eventBus->setCurrentTime(now()); 

// elsewhere in tests 
$eventBus->setCurrentTime(<point in time you want to test against>); 
+0

優秀的答案。我使用Laravel/PHPUnit,Laravel使用Carbon來處理日期 - 你的回答讓我從Carbon中找到以下代碼片斷:'Carbon :: setTestNow(Carbon :: now() - > addDay(3));'' – Chris

相關問題