unit-testing – 如何模拟CakePHP行为以进行单元测试

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

情况

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

我正在使用CakePHP 2.4.1.

我试过的

>阅读文档. The manual显示了如何为组件和助手执行此操作,但不为行为执行此操作.
>谷歌.我发现了什么:

> A Google Group post说它简直“不可能”.我不回答任何问题.
> An article解释如何模拟对象.非常接近.

该文章的代码如下:

$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应该是什么样子.

使用类注册表

与许多类一样,行为是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'],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);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


如何选择合适的 C++ Web 开发框架?
利用 C++ 框架构建高并发 Web 应用的策略
用 C++ 框架开发跨平台图形应用程序
golang框架中安全编码实践的最佳指南是什么?
golang框架与其他语言框架在设计理念上的区别有哪些?
C++ 图形框架与其他语言框架的比较
C++ 框架与其他 Web 开发框架的对比分析
使用 C++ 框架构建大型项目最佳实践
C++ 框架如何提高大型项目开发效率
C++ 框架中依赖注入的持续集成与部署工具
如何与社区协作和贡献到自定义 Golang 框架?
C++ 框架在大型项目中如何实现模块化开发
使用 C++ 框架开发跨平台 Web 应用
C++ 框架在大型项目中的优缺点
golang框架在性能上的优势体现在哪些方面?
C++ 框架在嵌入式系统内存优化中的优势
golang框架在人工智能与机器学习中的作用
如何扩展 Golang 框架以支持特定功能?
如何利用 Go Modules 和依赖项管理来自定义 Golang 框架?
Golang 框架中的性能优化技巧