我想尽可能地使用测试驱动开发 - 这是一种很好的工作方式.
我对Symfony2控制器创建并返回一个新Response对象这一事实感到不安.
我希望能够单独测试控制器.
你怎么做呢?
答案是将控制器创建为Plain Old PHP Object,将其注册为服务并使用Dependency Injection将新Response对象(或Response工厂)传递给它?
我正在编写一个将继承接口的类.将为该接口编写客户端代码,并编写用于支持它的类.我的想法是稍后我将为该接口编写其他类,这两个不同类的对象应该是完全可互换的.我没有为第一个类编写测试类,而是想为接口编写一个.
我的计划是编写一个测试类,它将为构造函数(依赖注入)获取工厂对象,并使用工厂创建被测试类的新实例.
这样,如果我想测试ClassA,我可以将ClassAFactory对象传递给测试类的构造函数,如果我想测试ClassB,我会传递一个ClassBFactory对象.这两个类都是可以互换的,因为只有公共方法应该被测试,这似乎是理想的.
但是测试构造函数呢?我是否会更好地编写一个抽象的测试类,并在继承抽象测试类的类中实现构造函数测试(不同的类可能以不同的方式实例化)?
如果我确实使用了第一个想法,我想我会测试每个被测试的类,例如:
class ClassATest extends [PHPUnit test case]
{
$myFactory = new ClassAFactory();
$myTest = new ClassTest($myFactory);
$myTest->test1();
$myTest->test2();
//etc.
}
Run Code Online (Sandbox Code Playgroud)
最好的方法是什么?我想要进行一般性测试,这样当我编写新类来实现公共接口时,我可以只使用与其他测试相同的测试对象.但是,看到不同的类会有不同的构造函数,或许编写一个抽象的测试类并为每个新对象扩展它会更好吗?你怎么看?
我从Symfony2烹饪书(http://symfony.com/doc/current/cookbook/security/entity_provider.html)跟踪了"如何从数据库加载安全用户(实体提供程序)"配方,除了我是不使用自定义实体提供程序 - 这意味着我的User类正在为角色使用延迟加载.
安全性中的防火墙/访问控制都可以正常工作.我有一些只有ROLE_ADMIN用户可以访问的路由和一些ROLE_USER用户可以访问的路由 - 这些工作正常.
问题是在我的基本模板中,我有一个显示如下的栏:
<p>Logged in as: {{ app.user.username }} {% if is_granted('ROLE_ADMIN') %}| <a href="{{ path('bassettprovidentia_skeleton_admindashboard') }}">Admin area</a> {% endif %}| <a href="#">Settings</a> | <a href="{{ path('bassettprovidentia_skeleton_logout') }}">Log out</a></p>
Run Code Online (Sandbox Code Playgroud)
即使我的用户在数据库中具有ROLE_ADMIN角色(并且可以访问仅限于该角色的URL),也不会显示"管理区域"链接!
以同样的形式,我有这个:
<p>Roles: {% for role in app.user.roles %}{{ role.name }} [{{ role.role }}]{% if not loop.last %}, {% endif %}{% endfor %}</p>
Run Code Online (Sandbox Code Playgroud)
它工作正常!显示用户拥有的所有角色!
我究竟做错了什么?
懒惰是否应该归咎于?
这不会导致其他地方出现问题.
我正在设计一个有两个依赖项的类.其中一个依赖类已经编写和测试.另一个还没写.
它发生在我身上,因为剩余的依赖关系将被编写以方便将要使用它的类,我应该首先编写后者,然后设计前者的接口,学习它应该做什么.
在我看来,这是制作代码的好方法.毕竟,只要主类在其构造函数中得到一个mock,我就可以编写它并在不知道它的依赖性不存在的情况下测试它,然后我可以创建依赖项,一旦我确定我知道我需要什么.
那么:我该怎么做?创建一个我修改的骨架类.也许是这样的:
class NonExistantSkeleton
{
public function requiredMethod1()
{
}
public function newlyDiscoveredRequirement()
{
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用PHPUnit模拟它,并设置存根等,以保持我的课程开发愉快?
这是要走的路吗?
这似乎是开发代码的好方法 - 在我看来比开发依赖更有意义,而不确定它将如何被使用.
下午好,
我正在编写一个脚本,允许新闻用户在网站上注册.
简而言之,这些是我计划的步骤:
register.php - 新用户填写表单,输入用户名,地址详细信息,公司名称和电子邮件地址.然后通过SSL将数据发回脚本.
register.php - 该脚本检查用户名或电子邮件地址是否尚未存储在数据库中.如果不是,则使用这些数据生成令牌,该令牌以超链接的形式通过电子邮件发送到电子邮件地址,该令牌和其余数据作为hyperlinlk的参数.使用的令牌是由一个秘密字符串构成的 - 这样,只有这个脚本才能生成一个可以使用其余数据重建的代码.
email - 单击超链接(SSL),从而通过SSL将数据通过$ _GET传递到下一个脚本.
verify.php - 使用传递的$ _GET数据和已知的秘密字符串重建令牌.如果哈希是相同的,我们知道令牌是由我们的一个脚本生成的.在单击"提交"(通过SSL将数据发布到自身)之前,系统会提示用户输入密码(两次).
verify.php - 在将新用户数据插入数据库之前,脚本检查用户名或电子邮件地址不存在,以及散列密码和salt.
电子邮件 - 向管理员发送电子邮件通知,告诉他们新用户已注册 - 新用户需要先获得批准才能登录.该电子邮件包含指向下一个脚本的链接,其中包含新用户的ID用户通过$ _GET传递给它.使用SSL.
confirm.php - 该脚本使用新用户的传递ID在可编辑字段(不是密码或盐)中显示已注册的所有详细信息.单击"确认"后,表单数据将通过SSL发回到同一脚本.
confirm.php - 脚本更新该用户的记录,并将新用户记录设置为"已确认".新用户收到电子邮件通知,现在可以登录.
这似乎很长,但有一系列步骤需要完成.
在将任何数据存储在我们的数据库之前,所有新用户必须验证其电子邮件地址 密码的传递不会超出需要的范围.它只是以原始形式通过POST传递回"verify.php"脚本,然后将其哈希.我将确保不会在服务器上记录SSL数据包的POST数据.这样,服务器上应该没有原始密码的记录,对吧?
生成并存储每个用户的随机盐 - 以防止彩虹表.
我错过了什么吗?我唯一的音乐会是通过SSL传输原始密码.虽然SSL可以防止嗅探,但我仍然不愿意将原始密码接收到服务器中.也就是说,我不希望通过对客户端进行散列来使项目易受"中间人"攻击.
任何人都可以建议我的方法有任何缺陷吗?我尝试使用Google搜索,虽然有一些适用的帖子,但整个过程似乎没有任何关系.我希望这个主题将有利于未来的访问者和我自己.
谢谢.
php ×5
phpunit ×2
symfony ×2
unit-testing ×2
class-design ×1
hash ×1
oop ×1
passwords ×1
registration ×1
twig ×1