如何在 PHPSpec 规范文件中创建可用于规范中所有示例的 class 变量
How to create class variables in a PHPSpec spec file that can be used for all examples in the spec
我有一个包含许多示例的 PHPSpec class。我希望能够在规范 class 中创建 class 变量,这些变量可以被 class.
中的任何示例函数使用
下面是一个非常简化的版本:
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 如何(巧妙地)实例化和引用被测 class。规范方法中对 $this
的引用实际上是指测试对象, 而不是 规范 class 本身。
但这意味着尝试使用 $this->class_variable
引用 class 变量引用测试对象上的 class 变量,而不是规范。
所以。如何在规范 class 本身的范围内创建一组可以在运行时由示例访问的变量?
我尝试过的事情:
- 将 class 变量放在构造函数中 – 示例仍然无法访问
- 使用
beConstructedWith
– 需要更改被测 class 才能对其进行测试。不是一个干净的解决方案。
- 当我要引用的公共对象是数据库记录时,我可以使用Eloquent通过id(或其他属性)引用它们,每次从模型中构建一个集合或class对象. 这可行,但很耗时,因为我需要在每个规范函数中构建集合或对象。我想在实例化规范 class 时构建这些集合和对象一次,并在整个 class.
中引用它们
我还没有尝试过的东西:
- 在规范 class 和被测 class 范围之外创建第三个对象,以容纳通用对象和变量,规范 class 可以访问它们运行时的方法(示例)。该解决方案可能有效,但它为规范增加了一层,如果有更清洁的解决方案,我希望避免这种情况。
注意: 我不希望 "alternatives" 以上述方式进行测试,除非它们仍然适合更广泛的需求。这个例子非常精简。实际上,我正在扩展 LaravelObjectBehavior
(https://github.com/BenConstable/phpspec-laravel), creating records in a test database using the spec's constructor via Factory and Faker classes (https://github.com/thephpleague/factory-muffin),并在测试后销毁它们(League\FactoryMuffin\Facade::deleteSaved() 在规范的析构函数中)。我希望能够在任意数量的规范函数中引用由模型(并由 FactoryMuffin 创建)表示的对象,因此我不必在每个规范函数中重新创建这些对象和集合。是的,我知道这超出了 "spec" 测试范围,但是当应用程序被绑定到模型时,与数据层交互的对象仍然是 "speccable",可以争论.
我目前正在使用 phpspec 2.2.1 和 Laravel 4.2
找到答案了。将 class 变量显式声明为 static
并且可以通过规范 class:
中的方法访问它们
class ThingImTestingSpec extends ObjectBehavior
{
private static $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']);
}
}
这适用于数组以及表示使用 Eloquent 构建的数据库记录的对象,例如
class LaravelAppClassImTestingSpec extends LaravelObjectBehavior
{
private static $Order_1;
function __construct()
{
$Order_1 = \Order::find(123);
}
function it_tests_a_thing()
{
//(the method has access to the static class variable via
//$this::$Order_1
}
}
我们目前在我们的软件中使用 PHPSpec v3。请使用 let
方法声明公共事物。快速示例:
<?php
class ExampleSpec extends \PhpSpec\ObjectBehavior
{
private $example; // private property in the spec itself
function let()
{
$this->example = (object) ['test1' => 'test1']; // setting property of the spec
parent::let();
}
function it_works()
{
var_dump($this->example); // will dump: object(stdClass)#1 (1) { ["test1"] => string(5) "test1" }
}
function it_works_here_as_well()
{
var_dump($this->example); // will dump same thing as above: object(stdClass)#1 (1) { ["test1"] => string(5) "test1" }
$this->example = (object) ['test2' => 'test2']; // but setting here will be visible only for this example
}
function it_is_an_another_example()
{
var_dump($this->example); // will dump same thing first two examples: object(stdClass)#1 (1) { ["test1"] => string(5) "test1" }
}
}
我有一个包含许多示例的 PHPSpec class。我希望能够在规范 class 中创建 class 变量,这些变量可以被 class.
中的任何示例函数使用下面是一个非常简化的版本:
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 如何(巧妙地)实例化和引用被测 class。规范方法中对 $this
的引用实际上是指测试对象, 而不是 规范 class 本身。
但这意味着尝试使用 $this->class_variable
引用 class 变量引用测试对象上的 class 变量,而不是规范。
所以。如何在规范 class 本身的范围内创建一组可以在运行时由示例访问的变量?
我尝试过的事情:
- 将 class 变量放在构造函数中 – 示例仍然无法访问
- 使用
beConstructedWith
– 需要更改被测 class 才能对其进行测试。不是一个干净的解决方案。 - 当我要引用的公共对象是数据库记录时,我可以使用Eloquent通过id(或其他属性)引用它们,每次从模型中构建一个集合或class对象. 这可行,但很耗时,因为我需要在每个规范函数中构建集合或对象。我想在实例化规范 class 时构建这些集合和对象一次,并在整个 class. 中引用它们
我还没有尝试过的东西:
- 在规范 class 和被测 class 范围之外创建第三个对象,以容纳通用对象和变量,规范 class 可以访问它们运行时的方法(示例)。该解决方案可能有效,但它为规范增加了一层,如果有更清洁的解决方案,我希望避免这种情况。
注意: 我不希望 "alternatives" 以上述方式进行测试,除非它们仍然适合更广泛的需求。这个例子非常精简。实际上,我正在扩展 LaravelObjectBehavior
(https://github.com/BenConstable/phpspec-laravel), creating records in a test database using the spec's constructor via Factory and Faker classes (https://github.com/thephpleague/factory-muffin),并在测试后销毁它们(League\FactoryMuffin\Facade::deleteSaved() 在规范的析构函数中)。我希望能够在任意数量的规范函数中引用由模型(并由 FactoryMuffin 创建)表示的对象,因此我不必在每个规范函数中重新创建这些对象和集合。是的,我知道这超出了 "spec" 测试范围,但是当应用程序被绑定到模型时,与数据层交互的对象仍然是 "speccable",可以争论.
我目前正在使用 phpspec 2.2.1 和 Laravel 4.2
找到答案了。将 class 变量显式声明为 static
并且可以通过规范 class:
class ThingImTestingSpec extends ObjectBehavior
{
private static $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']);
}
}
这适用于数组以及表示使用 Eloquent 构建的数据库记录的对象,例如
class LaravelAppClassImTestingSpec extends LaravelObjectBehavior
{
private static $Order_1;
function __construct()
{
$Order_1 = \Order::find(123);
}
function it_tests_a_thing()
{
//(the method has access to the static class variable via
//$this::$Order_1
}
}
我们目前在我们的软件中使用 PHPSpec v3。请使用 let
方法声明公共事物。快速示例:
<?php
class ExampleSpec extends \PhpSpec\ObjectBehavior
{
private $example; // private property in the spec itself
function let()
{
$this->example = (object) ['test1' => 'test1']; // setting property of the spec
parent::let();
}
function it_works()
{
var_dump($this->example); // will dump: object(stdClass)#1 (1) { ["test1"] => string(5) "test1" }
}
function it_works_here_as_well()
{
var_dump($this->example); // will dump same thing as above: object(stdClass)#1 (1) { ["test1"] => string(5) "test1" }
$this->example = (object) ['test2' => 'test2']; // but setting here will be visible only for this example
}
function it_is_an_another_example()
{
var_dump($this->example); // will dump same thing first two examples: object(stdClass)#1 (1) { ["test1"] => string(5) "test1" }
}
}