dovt85093 2010-11-25 20:04
浏览 49
已采纳

测试夹具数据

I've recently started using unit tests and it's been a blast so far.

However, I've bumped into a situation where my approach feels plain wrong and I can't wrap my head around a "good" solution.

The context for the code is an application for viewing tv broadcast schedules written in symfony, tested with sfPHPUnit2Plugin.

public function testLoadChannelBroadcasts() {

    $Start = new DateTime();
    $End = new DateTime();

    $Channels = ChannelTable::getChannelsWithBroadcastsTouchingTimeSpan($Start, $End);

    foreach ($Channels as $Channel) {
      $Channel->loadBroadcastsTouchingTimeSpan($Start, $End);
    }

    // test data

    $Broadcasts = $Channels[0]->Broadcasts;

    $assertion = $Broadcasts[0]->getDateTimeObject('start') <= $Start
     && $Broadcasts[0]->getDateTimeObject('end') >= $Start;

    $this->assertTrue($assertion, 'starts before scope, ends inside scope');

    $assertion = $Broadcasts[1]->getDateTimeObject('start') >= $Start
     && $Broadcasts[1]->getDateTimeObject('end') <= $End;

    $this->assertTrue($assertion, 'starts inside scope, ends inside scope');

    $assertion = $Broadcasts[2]->getDateTimeObject('start') >= $Start
     && $Broadcasts[2]->getDateTimeObject('end') >= $End;

    $this->assertTrue($assertion, 'starts inside scope, ends outside scope');

    $LongBroadcast = $Channels[1]->Broadcasts[0];

    $assertion = $LongBroadcast->getDateTimeObject('start') <= $Start
     && $LongBroadcast->getDateTimeObject('end') >= $End;

    $this->assertTrue($assertion, 'starts before scope, ends after scope');
}

The test communicates the purpose of the method, but the testing of data (fixtures) relies heavily on assumptions about what the data contains. Is there a better approach to this?

  • 写回答

1条回答 默认 最新

  • dongzexi5125 2010-11-25 20:48
    关注

    This is not really a unit test as it is right now, because you are testing the method outside its boundaries, by calling ChannelTable.

    The proper way of doing this would be to change:

    $Channels = ChannelTable::getChannelsWithBroadcastsTouchingTimeSpan($Start, $End);
    

    To:

    $Channels = array('yourdata', 'etc');
    

    This way, if ChannelTable fails to provide the correct data, your test doesn't fail, because it shouldn't.

    Remember, a unit test purpose is to test the unit (method) and nothing else. If your whole application fails to connect to a database and provide data, the unit test still passes because the method behaves as it should.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作