我一直在寻找在 Yii 应用程序开发中使用 TDD 的最佳方式。如今,大多数 Web 应用程序都由一个前端 API 层(通常是 JSON)组成,以提供对服务器和后端的异步调用。就我而言,这个应用程序中最常用的测试是单元测试和功能测试。后者在指南和书籍中最广泛地展示了利用 PHPUnit + Selenium,但 Behat + Mink 似乎也很酷(但我对它还不是很自信)
如果您曾经使用过使用浏览器(如 Selenium)的功能测试,您就会知道运行它们的次数越少,您的感觉就越好。这导致它们更慢,更难维护,有时(如使用 JS SDK 的弹出式 FB 登录)很痛苦。
在使用单个网页应用程序时,我关心测试我的 api 的 JSON 输出。我想使用类似单元测试的方法来测试这些功能,以便更快地进行更易于维护的测试。考虑到我的控制器的大部分操作对使用 accessControl 过滤器的仅登录用户可用,我想知道让我的测试启动和运行的最佳方法。
此刻我认为有两种方法可以做到这一点
- 使用 cUrl 指向所需的 enpoint 以获取 JSON 直接调用
- 控制器的功能
在第一个场景中,我可以使用固定装置,但我无法使用 Apache 模拟 CWebUser 类(模拟登录用户),当 cUrl 出现时,它由我的 CWebApplication 实例执行,该实例不是由 PHPUnit 执行的。我可以通过使我的所有 API 调用无状态并因此删除 accessControl 过滤器来解决这个问题。
在第二个中,我发现模拟 CWebUser 类的唯一方法是在我正在执行的测试类中覆盖它。在我不需要测试需要不同类型用户的用例之前,这种方法是有效的,而且我无法在运行时(或设置时)更改我的网络用户模拟。我发现模拟我的网络用户的唯一方法是您可以在下面找到的方法,这导致 $this->getMock('WebUser') 无论如何都不会影响配置文件中定义的 CWebApplication 的 WebUser(只读)单例。
下面是一个具体的例子:
class UserControllerTest extends CDbTestCase
{
public $fixtures=array(
/* NEEDED FIXTURES*/
);
public function testUserCanGetFavouriteStore() {
$controller = new UserController(1);
$result = json_decode($controller->actionAjaxGetFavStore());
$this->assertInternalType('array', $result->data);
$model = $result->data[0];
$this->assertEquals($model->name, "Nome dello Store");
}
}
class WebUser extends CWebUser {
public function getId() {
return 1;
}
public function getIsGuest() {
return false;
}
};
我想知道通过 API 密钥或用户/密码组合使用 api 接口进行身份验证是否有用。如果我转向几乎无状态的 API 集成,这没问题,但大多数时候我只有控制器的操作(仅允许登录用户)返回 Json 数据以填充前端。
任何人都可以建议我更好的方法吗?也许只是测试这种 JSON 输出没用?
此致