【发布时间】:2018-02-27 11:25:24
【问题描述】:
我有一个包含许多示例的 PHPSpec 类。我希望能够在规范类中创建可供类中任何示例函数使用的类变量。
下面是一个非常简化的版本:
class ThingImTestingSpec extends ObjectBehavior
{
private $common_variables_array = [
'property_1' => value_1,
'property_2' => 'Value 2'
];
function it_finds_a_common_property()
{
$object_1 = new ConstructedObject;
$this->find_the_common_property($object_1)->shouldReturn($this->common_variables_array['property_1']);
}
}
问题在于 PHPSpec 如何(巧妙地)实例化和引用被测类。在规范方法中对$this 的引用实际上是指测试对象,而不是规范类本身。
但这意味着尝试使用$this->class_variable 引用类变量会引用测试对象上的类变量,而不是规范。
所以。如何在规范类本身的范围内创建一组变量,这些变量可以在运行时由示例访问?
我尝试过的事情:
- 将类变量放在构造函数中 - 仍然无法通过示例访问
- 使用
beConstructedWith- 需要更改被测类,以便对其进行测试。不是一个干净的解决方案。 - 当我要引用的常见对象是数据库记录时,我可以使用 Eloquent 通过 id(或其他属性)引用它们,每次都从 Model 构建一个集合或类对象。 这可行,但很耗时,因为我需要在每个规范函数中构建集合或对象。我想在规范类被实例化时构建一次这些集合和对象,并在整个类中引用它们。
我还没有尝试过的事情:
- 在规范类和被测类的范围之外创建第三个对象来容纳通用对象和变量,这些对象和变量可以在运行时由规范类方法(示例)访问。此解决方案可能有效,但如果有更清洁的解决方案,它会在规范中添加一个我希望避免的层。
注意:我不是在寻找以上述方式进行测试的“替代方案”,除非它们仍然适合更广泛的需求。这个例子非常精简。在实践中,我正在扩展LaravelObjectBehavior (https://github.com/BenConstable/phpspec-laravel),使用规范的构造函数通过 Factory 和 Faker 类 (https://github.com/thephpleague/factory-muffin) 在测试数据库中创建记录,并在测试后销毁它们 (League\FactoryMuffin\Facade: :deleteSaved() 在规范的析构函数中)。我希望能够在任意数量的规范函数中引用由模型表示的对象(并由 FactoryMuffin 创建),因此我不必在每个规范函数中重新创建这些对象和集合。是的,我知道这超出了“规范”测试的范围,但是当应用程序被绑定到模型时,与数据层交互的对象仍然是“规范的”,这是可以争论的。
我目前正在使用 phpspec 2.2.1 和 Laravel 4.2
【问题讨论】: