【问题标题】:how to create a mock in a model test case如何在模型测试用例中创建模拟
【发布时间】:2012-06-22 07:45:56
【问题描述】:

也许我做错了。

我想测试一个模型(抗体)的 beforeSave 方法。此方法的一部分调用关联模型(物种)上的方法。我想模拟 Species 模型,但找不到方法。

是否有可能或者我正在做一些违背 MVC 模式的事情,从而试图做一些我不应该做的事情?

class Antibody extends AppModel {
    public function beforeSave() {

        // some processing ...

        // retreive species_id based on the input 
        $this->data['Antibody']['species_id'] 
            = isset($this->data['Species']['name']) 
            ? $this->Species->getIdByName($this->data['Species']['name']) 
            : null;

        return true;
    }
}

【问题讨论】:

    标签: unit-testing cakephp mocking phpunit cakephp-2.1


    【解决方案1】:

    假设您的 Species 模型是由 cake 由于关系创建的,您可以简单地执行以下操作:

    public function setUp()
    {
        parent::setUp();
    
        $this->Antibody = ClassRegistry::init('Antibody');
        $this->Antibody->Species = $this->getMock('Species');
    
        // now you can set your expectations here
        $this->Antibody->Species->expects($this->any())
            ->method('getIdByName')
            ->will($this->returnValue(/*your value here*/));
    }
    
    public function testBeforeFilter()
    {
        // or here
        $this->Antibody->Species->expects($this->once())
            ->method('getIdByName')
            ->will($this->returnValue(/*your value here*/));
    }
    

    【讨论】:

      【解决方案2】:

      嗯,这取决于注入“物种”对象的方式。 它是通过构造函数注入的吗?通过二传手?是继承的吗?

      这是一个构造函数注入对象的示例:

      class Foo
      {
          /** @var Bar */
          protected $bar;
      
          public function __construct($bar)
          {
              $this->bar = $bar;
          }
      
          public function foo() {
      
              if ($this->bar->isOk()) {
                  return true;
              } else {
                  return false;
              }
          }
      }
      

      那么你的测试会是这样的:

      public function test_foo()
      {
          $barStub = $this->getMock('Overblog\CommonBundle\TestUtils\Bar');
          $barStub->expects($this->once())
              ->method('isOk')
              ->will($this->returnValue(false));
      
          $foo = new Foo($barStub);
          $this->assertFalse($foo->foo());
      }
      

      这个过程与 setter 注入对象完全一样:

      public function test_foo()
      {
          $barStub = $this->getMock('Overblog\CommonBundle\TestUtils\Bar');
          $barStub->expects($this->once())
              ->method('isOk')
              ->will($this->returnValue(false));
      
          $foo = new Foo();
          $foo->setBar($barStub);
          $this->assertFalse($foo->foo());
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-19
        • 1970-01-01
        • 1970-01-01
        • 2023-04-02
        • 2013-12-04
        • 1970-01-01
        相关资源
        最近更新 更多