php - 为在 CakePHP 2 中使用 AuthComponent 的 Controller 编写单元测试

标签 php unit-testing cakephp authentication

我正在尝试测试允许编辑用户配置文件的 Controller 操作。除其他事项外,我想测试每个登录用户只能编辑自己的个人资料,而不能编辑其他人的个人资料。如果打破此限制,操作必须重定向到预定义的主页。

在这种情况下,我有一个 fixture 可以创建 ID = 1 的用户。所以我正在考虑以这种方式测试限制:

$data = $this->Users->User->read(null, 1); 
$this->Users->Auth->login($data); 
$this->testAction('/users/edit/2', array('method' => 'get')); 
$url = parse_url($this->headers['Location']); 
$this->assertEquals($url['path'], '/homepage'); 

测试通过了这个断言。所以下一步是检查执行 '/users/edit/1' 是否显示表单:

$this->testAction('/users/edit/1', array('method' => 'get', 'return' => 'vars'));
$matcher = array( 
  'tag' => 'form', 
  'ancestor' => array('tag' => 'div'), 
  'descendant' => array('tag' => 'fieldset'), 
); 
$this->assertTag($matcher, $this->vars['content_for_layout'], 'The edition form was not found');

但是这个断言失败了。在深入了解 debug() 之后,我发现 $this->Auth->user() 返回了全部信息,但是 $this->Auth->user('id') 返回 null。由于我在操作中使用后者进行比较,因此它的计算结果为 false 并导致 测试失败。

奇怪的是,它发生在测试时,而不是在浏览器中执行操作时。那么,测试此操作的正确方法是什么?

谢谢!

最佳答案

实际的正确答案应该是使用模拟对象而不是实际手动登录用户:

$this->controller = $this->generate('Users', array(
    'components' => array('Auth' => array('user')) //We mock the Auth Component here
));
$this->controller->Auth->staticExpects($this->once())->method('user') //The method user()
    ->with('id') //Will be called with first param 'id'
    ->will($this->returnValue(2)) //And will return something for me
$this->testAction('/users/edit/2', array('method' => 'get')); 

使用模拟是测试 Controller 最简单的方法,也是最灵活的方法

2015 年 3 月 11 日更新

你也可以模拟 AuthComponent 的所有方法

$this->controller = $this->generate('Users', array(
    'components' => array('Auth') // Mock all Auth methods
));

关于php - 为在 CakePHP 2 中使用 AuthComponent 的 Controller 编写单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8216434/

相关文章:

php - 意外的 T_CONSTANT_ENCAPSED_STRING

cakephp - Cake的ACL组件及 "ownership"的概念

php - 为什么 PHP array_diff 以这种方式工作

php - 使用 PHP 将用户输入的全文搜索查询解析为 MySQL 的 WHERE 子句

javascript - 获取 Recaptcha 2 与 PHP 页面通信时出现问题

java - 正在测试的同一类中的模拟私有(private)方法

cakephp - 无法创建简单的 CakePHP 插件

php - 在 INSERT 语句中使用多个 SELECT 防止竞争条件

java - Mockito when() 需要一个必须是 'method call on a mock' 错误的参数

c# - 如何确保在 NUnit 单元测试期间不访问文件系统和数据库?