【问题标题】:How to mock a CakePHP behavior for unit testing如何模拟 CakePHP 行为以进行单元测试
【发布时间】:2013-11-18 22:53:52
【问题描述】:

我刚刚开始在 CakePHP 中进行单元测试(耶!)并遇到了以下挑战。希望有人可以帮助我:-)

情况

我的模型在本地保存后使用行为将更改发送到 API。我想伪造在测试期间对 API 的所有调用(这些调用将单独测试)以节省 API 服务器上的负载,更重要的是,实际上不保存更改:-)

我使用的是 CakePHP 2.4.1。

我的尝试

  • 阅读文档。 The manual 展示了如何为组件和助手执行此操作,但不适用于行为。
  • 谷歌。我发现了什么:

文章中的代码如下:

$provider = $this->getMock('OurProvider', array('getInfo'));
$provider->expects($this->any())
    ->method('getInfo')
    ->will($this->returnValue('200'));

这可能是错误的方向,但我认为这可能是一个好的开始。

我想要什么

有效:一段代码,用于演示如何在 CakePHP 模型中模拟行为以进行单元测试。

也许这个问题会导致添加 CakePHP 手册作为额外的奖励,因为我觉得那里缺少它。

提前感谢您的努力!

更新 (2013-11-07)

我找到了this related question,它应该(部分)回答了这个问题。无需模拟 API,我可以创建模型将使用的行为测试。

我试图弄清楚 BehaviorTest 应该是什么样子。

【问题讨论】:

    标签: unit-testing cakephp mocking phpunit behavior


    【解决方案1】:

    使用类注册表

    与许多类一样,行为是added to the class registry,使用类名作为键,随后对同一对象的请求loaded from the classregistry。因此,模拟一个行为的方法就是在使用它之前将其放入类注册表中。

    完整示例:

    <?php
    App::uses('AppModel', 'Model');
    
    class Example extends AppModel {
    
    }
    class TestBehavior extends ModelBehavior {
    
        public function foo() {
            throw new \Exception('Real method called');
        }
    }
    
    class BehaviorExampleTest extends CakeTestCase {
    
        /**
         * testNormalBehavior
         *
         * @expectedException Exception
         * @expectedExceptionMessage Real method called
         * @return void
         */
        public function testNormalBehavior() {
            $model = ClassRegistry::init('Example');
            $model->Behaviors->attach('Test');
    
            $this->assertInstanceOf('TestBehavior', $model->Behaviors->Test);
            $this->assertSame('TestBehavior', get_class($model->Behaviors->Test));
            $this->assertSame(['foo' => ['Test', 'foo']], $model->Behaviors->methods());
    
            $model->foo();
        }
    
        public function testMockedBehavior() {
            $mockedBehavior = $this->getMock('TestBehavior', ['foo', 'bar']);
            ClassRegistry::addObject('TestBehavior', $mockedBehavior);
    
            $model = ClassRegistry::init('Example');
            $model->Behaviors->attach('Test');
    
            $this->assertInstanceOf('TestBehavior', $model->Behaviors->Test);
            $this->assertNotSame('TestBehavior', get_class($model->Behaviors->Test));
    
            $expected = [
                'foo' => ['Test', 'foo'],
                'bar' => ['Test', 'bar'],
                'expects' => ['Test', 'expects'], // noise, due to being a mock
                'staticExpects' => ['Test', 'staticExpects'], // noise, due to being a mock
            ];
            $this->assertSame($expected, $model->Behaviors->methods());
    
            $model->foo(); // no exception thrown
    
            $mockedBehavior
                ->expects($this->once())
                ->method('bar')
                ->will($this->returnValue('something special'));
    
            $return = $model->bar();
            $this->assertSame('something special', $return);
        }
    }
    

    【讨论】:

    • 哇,感谢您快速而完整的回复!马上就开始摆弄它! :-) 我会回过头来将其设置为答案或留下一些评论。
    • 像魅力一样工作:)
    猜你喜欢
    • 2018-04-04
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 2020-04-06
    相关资源
    最近更新 更多