簡體   English   中英

如何在PHPSpec規范文件中創建可用於規范中所有示例的類變量

[英]How to create class variables in a PHPSpec spec file that can be used for all examples in the spec

我有一個PHPSpec類有很多例子。 我希望能夠在spec類中創建類變量,可以由類中的任何示例函數使用。

以下是一個非常簡化的版本:

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(巧妙地)如何實例化並引用被測試的類。 spec方法中對$this引用實際上是指測試對象, 而不是 spec類本身。

但這意味着嘗試使用$this->class_variable引用類變量引用測試對象上的類變量,而不是規范。

所以。 如何在spec類本身的范圍內創建一組變量,這些變量可以在運行時由示例訪問?

我試過的事情:

  • 將類變量放在構造函數中 - 示例仍然無法訪問它們
  • 使用beConstructedWith - 需要更改被測試的類,以便進行測試。 不是一個干凈的解決方
  • 當我想引用的公共對象是數據庫記錄時,我可以使用Eloquent通過id(或其他屬性)引用它們,每次都從Model中構建一個集合或類對象。 這是有效的,但是非常耗時 ,因為我需要在每個spec函數中構建集合或對象。 我想在實例化spec類時構建這些集合和對象,並在整個類中引用它們。

我還沒有嘗試過的事情:

  • 在spec類和被測試類的范圍之外創建第三個對象,以容納通用對象和變量,這些對象和變量可以在運行時由spec類方法(示例)訪問。 這個解決方案可以工作,但是如果有更清晰的解決方案,它會為我要避免的規范添加一個層。

注意:我不是在尋找以上述方式進行測試的“替代方案”,除非它們仍然適合更廣泛的需求。 這個例子非常簡單。 在實踐中,我正在擴展LaravelObjectBehaviorhttps://github.com/BenConstable/phpspec-laravel ),使用spec的構造函數通過Factory和Faker類在測試數據庫中創建記錄( https://github.com/thephpleague/ factory-muffin ),並在測試后銷毀它們(在規范的析構函數中的League \\ FactoryMuffin \\ Facade :: deleteSaved())。 我希望能夠在任意數量的spec函數中引用Model所代表的對象(並由FactoryMuffin創建),因此我不必在每個spec函數中重新創建這些對象和集合。 是的,我知道這個步驟超出了“規范”測試的范圍,但是當應用程序被綁定到模型時,與數據層交互的對象仍然是“可指定的”,可以說是有爭議的。

我目前正在使用phpspec 2.2.1和Laravel 4.2

我們目前在我們的軟件中使用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" }
    }
}

找到了答案。 顯式地將類變量聲明為static ,並且可以通過spec類中的方法訪問它們:

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
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM