2015-10-14 33 views
2

我正在写一个单元测试使用CakePHP的一个方法当作对象TimeHelperCakePHP的TimeHelper时间戳通过PHPUnit的

public function testData() 
{ 

    $timestamp = (string)Time::now()->i18nFormat('YYYY-MM-dd HH:mm:ss'); 
    // dump($timestamp); 
    // "2015-10-14 23:25:33" 

    ... 

    # data request should update the last_checkin field 
    $screen = TableRegistry::get('Screens')->get(1); 
    $this->assertEquals($timestamp, $screen->last_checkin); 
} 

我真的很困惑,为什么它的工作原理在控制器,并从dump()返回是正确的。但是,单元测试失败以下消息:

1) App\Test\TestCase\Controller\ScreensControllerTest::testData 
Failed asserting that Cake\I18n\Time Object &000000001a943b50000000016cb13674 (
    'date' => '2015-10-14 23:25:33.000000' 
    'timezone_type' => 3 
    'timezone' => 'UTC' 
) matches expected '2015-10-14 23:25:33'. 

/mysite/tests/TestCase/Controller/ScreensControllerTest.php:103 

为什么assertEquals()认为这是一个对象时dump()(和save()在我的控制器),认为它是一个字符串?

这是一个TimeHelper错误?一个phpunit错误?或者我错过了什么?

回答

1

Is this a TimeHelper bug? A phpunit bug? Or am I missing something?

从阅读关于__toString()开始阅读。阅读关于其他魔法的方法不会受到任何影响!你可以用它们做一些奇特的事情。然后check the time class

public function __toString() 
{ 
    return $this->i18nFormat(); 
} 

的assertEquals()认为这是它到底是什么 - 一个对象。

假设在这里为你的save()在后台使用Table :: save()会在后台做更多的复杂操作,但是在进程结束时,如果字段是datetime类型的话,它会在数据库中以datetime字符串结尾。这是因为Cake知道模式中的字段类型并将对象转换为正确的格式。

我想你的意思是Debugger::dump()(更具体一点!) - 由于某种原因我把它转换为字符串,老实说,我懒得看现在的确切路线和原因。但我认为你已经明白了发生了什么。

+0

非常感谢您雄辩的回答。我现在明白了这个问题,但我仍然困惑为什么将TimeHelper对象作为字符串投射并不会触发魔术__toString()。 PHP文档不讨论这一点。 – emersonthis

+0

好的。所以还是有点神秘。使用'$ timestamp - > __ toString()'可以让我的测试通过本地。但在circleCI中失败:'PHP致命错误:调用string_上的成员函数__toString() – emersonthis