对此有几点想法。
您的用户模型正在与合作者合作以实现其自己的行为 - 该合作者是 hash_hmac 函数。PHPSpec 的黄金法则是  Subject Under Specification,一次处理一个类,稍后再考虑协作者的实现细节。我发现这有助于我在设计课程时考虑到关注点分离原则,而且我经常发现自己在问这个问题——这个课程真正关心的是什么?
例如,您UserModel不应该真正关心您的系统使用哪种哈希算法来保护密码。然而,它可以知道一个对象,称为它HashingProvider,它能够散列密码,甚至只接收一个或多个字符串并返回某种散列表示。
通过以这种方式重新构建您的架构UserModel,您将能够充分利用 PHPSpec 中的 Mocking(这里很棒)来专注于实现您的UserModel第一个,然后继续HashingProvider
您的规范可能如下所示:
<?php
namespace spec;
use PHPSpec2\ObjectBehavior;
class User extends ObjectBehavior
{
   function it_should_be_initializable()
   {
        $this->shouldHaveType('User');
   }
   /**
    * @param /Some/HashingProvider $hashProvider
    */
   function it_should_authenticate_if_proper_signature_given($hashProvider)
   {
      $this->setEmail('email');
      $this->setPassword('password');
      $hashProvider->hash('email', 'password')->willReturn('signature');
      $this->authenticate('signature', $hashProvider)->shouldReturn(true);
   }
   /**
    * @param /Some/HashingProvider $hashProvider
    */
   function it_should_not_authenticate_if_invalid_signature_given($hashProvider)
   {
      $this->setEmail('email');
      $this->setPassword('password');
      $hashProvider->hash('email', 'password')->willReturn('signature');
      $this->authenticate('bad_signature', $hashProvider)->shouldReturn(false);
   }
}
然后,您的用户模型可以按照您的规范描述的方式使用该协作者:
<?php
class User extends Model
{
    public function authenticate($signature, $hashProvider)
    {
        $hash = $hashProvier->hash($this->email, $this->password);
        if ($hash == $signature)
            $this->_authenticated = true;
        return $this->_authenticated;
    }
}