如何构建一段时间内发生的进程的测试?

时间:2016-01-15 08:29:34

标签: php unit-testing testing

构建直接意义上没有结果的代码测试的方法是什么?

我们说我们有一个非常简单(但非常粗鲁)的过程:

  • 用户注册网站
  • 两天过去了
    • 发送提醒电子邮件
    • 更新一些数据库字段
  • 十天过去了
    • 发送" c' ya"电子邮件
    • 删除帐户

我可以为每组子任务编写测试(发送电子邮件,更新数据库等)。但是,我如何编写结构良好的测试,其内容如下:

"注册后两天,应发送提醒电子邮件" "注册后十天,帐户被删除"

虽然我使用PHP和PHPUnit,但我觉得问题可能/可能不是语言无关。

1 个答案:

答案 0 :(得分:1)

基于您的活动机制的实施。比如,当代码中的某个事件监听器收到带有用户ID的事件user:reminder时,您只需要:

1)通过手动发送该事件来测试提醒 - 发送脚本:

$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 / replacable time-getter上继续:

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

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