如何在 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 本身的范围内创建一组可以在运行时由示例访问的变量?

我尝试过的事情:

我还没有尝试过的东西:

注意: 我不希望 "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" }
    }
}