【问题标题】:Testing class against several traits in PHPUnit针对 PHPUnit 中的几个特征测试类
【发布时间】:2016-10-15 16:07:44
【问题描述】:
我正在测试我的 Validator php 类。该类将其验证器方法作为特征。所以src文件夹中有Validator.php文件,test文件夹中有validatorMethods.php和ValidatorTest.php文件。
我想使用一些不同的 validatorMethods.php 文件测试 Validator 类,以便加载验证器方法的不同特征或执行其他任何操作来提供验证器方法的一些特征来针对这些方法测试 Validator 类。
我曾想过将特征放入数组中,然后将特征注入到循环中的 Validator 类中。但这并不是将特征注入对象的方法......
那么如何针对各种特征测试类?也许更好的是使用每个使用不同特征的对象?
【问题讨论】:
标签:
php
unit-testing
testing
phpunit
traits
【解决方案1】:
如果我理解正确的话,你有一个 Validator 类,你想用它动态实现不同的特征。这不是特性的设计目的。
特征用于在不同类之间共享通用功能,而不需要它们扩展同一个类。相反,您想要做的是使您的每个特征成为实现接口的独立类。然后您可以将其传递给您的 Validator 课程。
看起来像这样:
interface ValidatorMethod {
public function validate($input);
}
class NumberValidator implements ValidatorMethod {
public function validate($input) {
return is_numeric($input);
}
}
class IntegerValidator implements ValidatorMethod {
public function validate($input) {
return is_integer($input);
}
}
class Validator {
private $validators = [];
public function addValidator (ValidatorMethod $method) {
$validators[] = $method;
}
public function validate($input) {
foreach ($validators as $validator) {
if (!$validator->validate($input)) {
return false;
}
}
return true;
}
}
在这种情况下,您将为每个 ValidatorMethod 对象编写单独的测试,以验证它们是否正确通过。至于Validator 类,您将编写通过模拟ValidatorMethod 的测试,该测试将根据需要通过和失败。例如,如果您想让所有验证器运行而不管之前验证器的通过/失败。
测试看起来像这样:
class ExampleValidatorMethodTest {
public function testValidatePass() {
$method = new NumberValidator();
$this->assertTrue($method->validate(1));
}
}
class ValidatorTest {
public function testSingleMethod() {
$method = $this->getMockBuilder('ValidatorMethod')
->getMock();
$input = 'foo';
$method->expects($this->once())
->with($input);
->will($this->returnValue(True));
$validator = new Validator();
$validator->addValidator($method);
$this->assertTrue($validator->validate($input));
}
public function testMultipleMethods() {
$method1 = $this->getMockBuilder('ValidatorMethod')
->getMock();
$method2 = $this->getMockBuilder('ValidatorMethod')
->getMock();
$input = 'foo';
$method1->expects($this->once())
->with($input);
->will($this->returnValue(True));
$method2->expects($this->once())
->with($input);
->will($this->returnValue(True));
$validator = new Validator();
$validator->addValidator($method1);
$validator->addValidator($method2);
$this->assertTrue($validator->validate($input));
}
}
可以在测试中进行一些优化以使代码更简单,但这些示例只是为了让您了解您想要做什么。