0

phpspec で非常に単純なクラスをテストしようとしています。

テストする必要のあるクラスのメソッド

/**
 * @param Store $session
 */
function __construct(Store $session)
{
    $this->session = $session;
}

/**
 * @param Store $session
 */
function __construct(Store $session)
{
    $this->session = $session;
}

/**
 * Set the current order id
 *
 * @param $orderId
 */
public function setCurrentOrderId($orderId)
{
    $this->session->set($this->sessionVariableName, $orderId);

    return $this;
}

/**
 * Get the current order id
 *
 * @return mixed
 */
public function getCurrentOrderId()
{
    return $this->session->get($this->sessionVariableName);
}

そしてテストの一部

use Illuminate\Session\Store;


class CheckoutSpec extends ObjectBehavior
{
    function let(Store $session)
    {
        $this->beConstructedWith($session);
    }

    function it_is_initializable()
    {
        $this->shouldHaveType('Spatie\Checkout\Checkout');
    }

    function it_stores_an_orderId()
    {
        $this->setCurrentOrderId('testvalue');

        $this->getCurrentOrderId()->shouldReturn('testvalue');

    }
}

残念ながら、テストはit_stores_an_orderIdこのエラーで失敗しますexpected "testvalue", but got null.

メソッドsetCurrentOrderIdgetCurrentOrderIdが職人の手直しで使用される場合、それらは問題なく機能します。

私のテスト環境では、セッションのセットアップに問題があるようです。

この問題はどのように解決できますか?

4

1 に答える 1

1

実際にテストしようとしているのは、クラスだけではありません。PHPSpec 仕様 (および一般的な単体テスト) は、分離して実行することを意図しています。

この場合に本当に必要なのは、クラスが意図したとおりに機能することですよね? Store クラスを単純にモックし、そこから必要なメソッドが呼び出されていることだけを確認し、返された結果があればそれをモックします。このようにして、クラスが意図したとおりに機能し、すでに完全にテストされているものをテストしないことを引き続き知ることができます。

これを行う方法は次のとおりです。

function it_stores_an_orderId(Store $session)
{
    $store->set('testvalue')->shouldBeCalled();
    $store->get('testvalue')->shouldBeCalled()->willReturn('testvalue');

    $this->setCurrentOrderId('testvalue');
    $this->getCurrentOrderId()->shouldReturn('testvalue');

}

それでも他のクラスのいくつかを直接関与させたい場合は、テスト環境をより制御できるため、Codeception や PHPUnit のようなものがより適切かもしれません。

ただし、それでも PHPSpec でこれを行いたい場合は、このパッケージで可能かもしれません (ただし、自分で試したことがないため、保証はありません)。

于 2014-08-23T06:46:55.377 に答える